2013-05-21 28 views
5

mam kod w Delphi, który wykonuje następujące czynności:po zakończeniu() wątku (klasy TThread), czy kończy się każde dziecko tego wątku?

procedure THilo.Execute; // (which is the thread) 
begin 
    inherited; 
    FreeOnTerminate := True; 
    while not Terminated do 
    begin 
    (...) 
    Sleep(100); 
    end; 
end; 

a teraz gdzieś indziej, w innym wątku (lub GUI) możemy to zrobić:

var 
    Hilo2: THilo; 
begin 
    Hilo2 := THilo.Create(True); 
    Hilo2.start; 
    Hilo2 := THilo.Create(True); 
    Hilo2.start; 
end; 

teraz mamy wykonywane 2 razy ten sam wątek i działają równolegle. Co się stanie, jeśli zrobimy to teraz ?:

Hilo2.Terminate; 

Czy to zakończy oba wątki, czy tylko 1, lub co? również, jeśli chcielibyśmy go zakończyć, możemy to osiągnąć przez .Resume()?

góry dzięki

Odpowiedz

8

Po utworzeniu drugiego gwintu została zastąpiona lokalną zmienną Hilo2 ze wskaźnika do drugiego obiektu - wskaźnik pierwszego obiektu jest zagubiony i nie masz już żadnego odniesienia do niej (lub droga aby to kontrolować). Spowoduje to wyciek pamięci, jeśli wątek nie zakończy się sam, a nie, wywołanie zakończenia nie zatrzyma obu wątków, tylko ostatni utworzony z tą zmienną jako odniesieniem. Ponadto, nie ma potrzeby wywoływania inherited w metodzie TThread z Execute - nie ma nic do odziedziczenia (metoda wykonania TThread jest abstrakcyjna, nic nie robi).

+0

Dzięki J, miałem w swoim programie to i nie mogłem zakończyć wątków , więc byłoby to naprawione za pomocą tablicy TThread, prawda? jak 'Hilo [i]: = THilo.Create (prawda); Hilo [i] .start; ' – user2308704

+1

Oh - inny doświadczony programista wielowątkowy Delphi. To sprawia, że ​​co najmniej dwie z nas :) –

+3

Ponieważ używane jest 'FreeOnTerminate = True', jeśli wątek kończy się przedwcześnie (nieprzechwycony wyjątek, itp.), Wywołanie' Terminate() 'może się nie udać (lub, co gorsza, uszkodzić pamięć) jeśli wątek już zniknął. 'FreeOnTerminate = True' powinno być używane tylko dla wątków tworzenia i zapominania. Jak tylko będziesz musiał dotknąć zewnętrznego wątku ** z powodu ** (zawieszenie/wznowienie, zakończenie/oczekiwanie, aktualizacje/dostęp do członków, itp.), Nie używaj 'FreeOnTerminate = True'! –