Перехват OnTerminate от нескольких потоков

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

Перехват OnTerminate от нескольких потоков

Сообщение coyot.rush » 29.12.2010 15:04:16

Имеем код
Код: Выделить всё
unit main;
{$ifdef FPC}{$mode objfpc}{$h+}{$endif}
interface
uses
mseglob,mseguiglob,mseguiintf,mseapplication,msestat,msemenus,msegui,
msegraphics,msegraphutils,mseevent,mseclasses,mseforms,classes,sysutils,
msesimplewidgets,msewidgets;

type
tmainfo = class(tmainform)
   tbutton1: tbutton;
procedure OnTreadTerminate(Sender: TObject);
   procedure _on_run(const sender: TObject);
end;

TTestThread = class(Tthread)   
  protected
    procedure Execute; override;
  public

end;

var
mainfo: tmainfo;
t1,t2,t3:TTestThread;
implementation
uses
main_mfm;

procedure tmainfo.OnTreadTerminate(Sender: TObject);
var
y:TThreadID;
begin
if Sender is TTestThread  then
begin
y:=TTestThread(Sender).Handle;
if y=t1.handle then begin showmessage('t1'+' (handle='+inttostr(y)+')') end;
if y=t2.handle then begin showmessage('t2'+' (handle='+inttostr(y)+')') end;
if y=t3.handle then begin showmessage('t3'+' (handle='+inttostr(y)+')') end;
end;

end;


procedure test();
begin
T1:=TTestThread.Create(True);
T2:=TTestThread.Create(True);
T3:=TTestThread.Create(True);

T1.Onterminate:=@mainfo.OnTreadTerminate;
T2.Onterminate:=@mainfo.OnTreadTerminate;
T3.Onterminate:=@mainfo.OnTreadTerminate;

T1.Resume;
T2.Resume;
T3.Resume;

end;

procedure tmainfo._on_run(const sender: TObject);
begin
test;
end;

procedure TTestThread.Execute;
begin
sleep(50*round(random(2))+50);
end;

end.


1)Интересует вопрос не получу ли я AV и прочие "радости" при одновременном доступе нескольких потоков к процедуре OnTreadTerminate ?
2)OnTreadTerminate выполняется в главном потоке , как и в delhpi ?
3)Thread.Handle и Thread.ThreadID в чем разница ?
4) WRITE_DEBUG попадает в конечный релиз (сборка без отладочной информации)?

Добавлено спустя 9 часов 55 минут 12 секунд:
По поводу 1) Жизнь и смерть в режиме run-timehttp://www.delphikingdom.com/asp/viewitem.asp?catalogid=342, но там кнопки у меня потоки :?:
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: Перехват OnTerminate от нескольких потоков

Сообщение Sergei I. Gorelkin » 30.12.2010 15:38:54

1,2) Одновременного доступа к OnTerminate не будет, т.к. это событие вызывается через Synchronize и потому выполняется в главном потоке. Но deadlock при определенных обстоятельствах возможен.
3) Это специфика WinAPI, не в windows используется что-то одно. После того, как поток завершился, но объект TThread еще не освобожден, вновь запущенный поток может иметь тот же ThreadID, но Handle всегда уникален.
4) Если речь о макросе в исходниках RTL, то зависит от того, как собирали RTL (был ли определен символ, включающий эту отладку -- а он включается сам по себе, независимо от debug/release), опции сборки проекта не влияют.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1407
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Перехват OnTerminate от нескольких потоков

Сообщение coyot.rush » 30.12.2010 17:09:00

deadlock при определенных обстоятельствах возможен.

Вот в этом случае
Для нормальной синхронизации главного и вторичного потока метода Synchronize недостаточно. Представьте себе такую ситуацию: в методе главного потока мы ожидаем завершения вторичного потока (не важно, каким образом, важно то, что этот метод не вернет управление главному потоку до тех пор, пока вторичный поток не завершится), а в это время вторичный поток вызывает метод Synchronize. В результате возникнет взаимоблокировка: метод главного потока не может завершиться пока не завершится вторичный поток, а вторичный поток не может завершиться, пока не будет выполнен метод Synchronize (а для этого нужно, чтобы главный поток вернулся в цикл обработки сообщений). Для разрешения этой ситуации существует функция CheckSynchronize, вызов которой приводит к выполнению всех методов, находящихся в данный момент в очереди SyncList, и возвращению управления из всех методов Synchronize, вызванных вторичными потоками.

Многопоточные программы в Delphi изнутри http://symmetrica.net/Delphi/threads.htm
Т.е. не следует делать еще одну проверку на существование потока. Я так понял для обновления данных необходимо назначить еще одну процедуру подобную OnTerminate (Обработчик событий), что вроде UpdateData(const sender: TObject,SomeData:SomeType...)

Это специфика WinAPI, не в windows используется что-то одно. После того, как поток завершился, но объект TThread еще не освобожден, вновь запущенный поток может иметь тот же ThreadID, но Handle всегда уникален.

Только Windows?
Код: Выделить всё
FThreadID: TThreadID; // someone might need it for pthread_* calls
это же *nix потоки

4) Если речь о макросе в исходниках RTL, то зависит от того, как собирали RTL (был ли определен символ, включающий эту отладку -- а он включается сам по себе, независимо от debug/release), опции сборки проекта не влияют.

Вот куда откуда берутся лишние килобайты :roll:
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: Перехват OnTerminate от нескольких потоков

Сообщение Sergei I. Gorelkin » 30.12.2010 19:39:30

Я к тому, что только в Windows у потока два разных идентификатора (Handle и ID), в *nix он только один, а в какое свойство TThread он "отображается" - уже другой вопрос.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1407
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград


Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Рейтинг@Mail.ru