2013-05-21 22 views
5

Ho un codice a Delfi, che esegue le seguenti operazioni:quando si termina() una discussione (classe TThread), esce ogni figlio di questa discussione?

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

e ora da qualche altra parte, in un altro thread (o la GUI) facciamo questo:

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

ora abbiamo eseguito 2 volte lo stesso thread e funzionano parallelamente. Che cosa succede se facciamo ora questa ?:

Hilo2.Terminate; 

sarà presente sospendere entrambi i fili o solo 1, o che cosa? inoltre, se volessimo interromperlo, potremmo raggiungere questo risultato tramite .Resume()?

Grazie in anticipo

risposta

8

Quando si crea il secondo thread si sta sovrascrivendo la variabile locale Hilo2 con un puntatore al secondo oggetto - puntatore del primo oggetto viene perso e non hai più alcun riferimento ad esso (o un modo per controllarlo). Ciò si tradurrà in una perdita di memoria se il thread non si termina e, no, la chiamata terminate non fermerà entrambi i thread, solo l'ultimo creato con quella variabile come riferimento. Inoltre, non c'è bisogno di chiamare inherited nel metodo Execute di un TThread - non c'è nulla da ereditare (il metodo di esecuzione di TThread è astratto, non fa nulla).

+0

Grazie J, ho avuto nel mio programma questo e non è stato possibile terminare i thread in modo che venisse corretto solo con un array di TThread, giusto? come 'Hilo [i]: = THilo.Create (True); Hilo [i] .start; ' – user2308704

+1

Oh - un altro esperto sviluppatore multithread Delphi. Questo rende almeno due di noi :) –

+3

Inoltre, dal momento che 'FreeOnTerminate = True' è in uso, se il thread termina prematuramente (eccezione non rilevata, ecc.), Quindi chiamare' Terminate() 'potrebbe non funzionare (o peggio, memoria corrotta) se il thread è già andato. 'FreeOnTerminate = True' dovrebbe essere usato solo per i thread create-and-forget. Non appena si deve toccare esternamente un thread per ** qualsiasi ** motivo (sospendere/riprendere, terminare/attendere, aggiornamenti/accessi ai membri, ecc.), Non utilizzare 'FreeOnTerminate = True'! –