Текущий архив: 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.009 c