Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.01.24;
Скачать: CL | DM;

Вниз

Треды в дельфи   Найти похожие ветки 

 
evger   (2009-12-06 14:40) [0]

Просьба помочь по следующим вопросам
1. Является ли property тредо-безопасным, например в приложении используется передача информации между тредами,

MyThread = class(TThread)
...
property Status: integer read fStatus;

из главного процесса используется вывод статуса треда по таймеру
Label1.Caption := inttostr(MyThread.Status);

а в Execute треда
while (true) do begin
 ...
 fStatus := ...;
 ..
end;

так можно писать или необходимо что-то вроде
while (true) do begin
   ...
   CriticalSection.Enter;
   fStatus := ...;
   CriticalSection.Leave;
   ...
end.

2. Есть объект созданый в главном потоке, ну например
TMyObject = class (TObject)
procedure SomeMethod;

procedure TMyObject.SomeMethod;
begin
  ShowMessage("Some methodm in MyObject");
end;

TMyThread = class(TThread);
property MyObject: TMyObject write fMyObject;

MyObject := TMyObject.Create;
MyThread := TMyThread.Create(true);
MyThread.MyObject := MyObject;
MyThread.Resume;

...

procedure TMyThread.Execute;
begin
  fMyObject.SomeMethod;
end;

В этом случае метод выполнится в контексте главного потока или MyThread?
Можно так вообще делать?
Если создано несколько тредов TMyThread и они запущены одновременно и могут одновременно вызвать SomeMethod будут проблемы и если да как от этого защититься?

3. Если в поток также как в пункте 2 предается другой поток, вот например

TMyPublicThread = class (TThread)
procedure SomeMethod;

procedure TMyPublicThread.SomeMethod;
begin
  ShowMessage("Some methodm in MyObject");
end;

TMyThread = class(TThread);
property MyPublicThread: TMyPublicThread write fPublicThread;

MyPublicThread := TMyPublicThread.Create;

MyThread := TMyThread.Create(true);
MyThread.MyPublicThread := MyPublicThread;
MyThread.Resume;

...

procedure TMyThread.Execute;
begin
  fPublicThread.SomeMethod;
end;

в этом случае SomeMethod выполнится в контексте PublicThread?
Опять же если несколько тредов будут использовать метод из PublicThread чем это черевато?

Заранее спасибо.

P.S. если что-то криво спросил или непонятен код, просьба не ругаться сразу, я пытаюсь разобраться как работают потоки, сталкиваюсь первый раз


 
MBo ©   (2009-12-06 15:07) [1]

procedure TMyThread.Execute;
begin
 fMyObject.SomeMethod;
end;

выполнится в контексте вторичного потока MyThread.
Если их несколько, нужна синхронизация

procedure TMyThread.Execute;
begin
 fPublicThread.SomeMethod;
end;

выполнится в MyThread


 
evger   (2009-12-06 15:31) [2]

По пункту 3:


> procedure TMyThread.Execute;
> begin
>  fPublicThread.SomeMethod;
> end;
>
> выполнится в MyThread
>
>


т.е не в PublicThread? Хм.

Просто у меня щас происходит следующее.

В PublicThread есть массив, SomeMethod добавляет в него элемент.
Получается что этот код исполняется в контексте MyThread, но меняет массив находящийся в PublicThread -
фактически все что мне нужно это защитить массив, заключив код добавляющий в массив элемент в крит. секцию.
И соответственно, все остальные обращение к массиву в PublicThread тоже. Так?

По 2 пункту, подскажите как синхронизировать.
Например метод SomeMethod пишет в файл

procedure SomeMethod(str: string);
var f: text;
begin
 assignfile(f, "somefile.txt");
 append(f);
 writeln(f, str);
 closefile(f);
end;

Тут нужно, что то вроде Synchronize(SomeMethod) или тоже крит. секцию?

И по 1 пункту, хотелось бы тоже узнать, можно так делать или нет.


 
Игорь Шевченко ©   (2009-12-06 15:50) [3]

По п.1 - пофиг. Можно работать с критической секцией, можно без нее.


 
Игорь Шевченко ©   (2009-12-06 15:52) [4]


> в этом случае SomeMethod выполнится в контексте PublicThread?
>  


Все, что выполняется в Execute, выполняется в контексте того потока, чей метод Execute, если не предпринято никаких специальных действий, например Synchronize, метод, указанный в котором, выполняется в контексте главного потока приложения.


 
MBo ©   (2009-12-06 16:08) [5]

>фактически все что мне нужно это защитить массив, заключив код >добавляющий в массив элемент в крит. секцию.
>И соответственно, все остальные обращение к массиву в PublicThread тоже. Так?
В общем -  да. В конкретных ситуациях возможны и другие решения.

>Например метод SomeMethod пишет в файл
Тут не видно, что что-то нужно синхронизировать.
То, что SomeMethod - метод другого потока, не важно до тех пор, пока не используются переменные того потока, которые могут изменяться из его Execute


 
evger   (2009-12-06 17:04) [6]

Всем огромное спасибо за помощь.
Кажись все понял, если не так, то поправьте:

Итак
1 тезис:
TThread это тот же объект, только у него есть процедура Execute которая выполняется в отдельном потоке, соответственно если я запускаю из Execute какие-то методы, свои или методы других объектов они выполняются в контексте моего моего потока.

2 тезис:
Если я обращаюсь к методу какого-либо потока из главного потока или из любого другого, то код исполняется в контексте потока из которого я обращаюсь.
Но используется память выделенная под этот объект или тред.

3 тезис:
Проблемы возникают тогда, когда есть возможность обратиться к одной и той же переменной из нескольких потоков одновременно, чтобы избежать проблемы необходимо заключить все такие обращения в крит секцию


 
Юрий Зотов ©   (2009-12-07 02:10) [7]

1 - да, но если запуск происходит через метод Synchronize, то код будет выполнен в главном потоке.

2 - да, но тоже с учетом возможности обращения через Synchronize.

3 - да, но критические секции - не единственный способ синхронизации. Кроме того, если потоки эту переменную только читают, то синхронизация может и вовсе не потребоваться. Все определяется конкретным кодом.



Страницы: 1 вся ветка

Текущий архив: 2010.01.24;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.008 c
4-1227154029
Riply
2008-11-20 07:07
2010.01.24
IoCreateSymbolicLink. Требования к параметрам.


1-1233798973
ply
2009-02-05 04:56
2010.01.24
Разная процедура для каждой формы.. как?


15-1258407522
K-one
2009-11-17 00:38
2010.01.24
Const Массив


15-1258520711
_
2009-11-18 08:05
2010.01.24
Восстановить битый фильм.


15-1258709445
Lebos
2009-11-20 12:30
2010.01.24
интерполяция