2014-10-13 9 views
5

Dire, ho una classe C++ che include un puntatore del thread come variabile membro. Il thread continua a funzionare finché il programma non si chiude. Se cancello il puntatore nel distruttore, sembra che il thread non sia ancora finito in quel momento? Qual è la migliore pratica per gestire questo o alcuni trucchi?Come eliminare in modo sicuro un puntatore del filo in un distruttore?

codice di esempio:

class Car { 
public: 
    Car(); 
    ~Car(); 
private: 
    boost::thread *m_runningThreadPtr; 
}; 


Car::Car() { 
    m_runningThreadPtr = new boost::thread(); 
} 

Car::~Car() { 
    delete m_runningThreadPtr; // The thread should be still running now. 
            // Problematic if it was deleted here? 
} 
+1

Provare a gestire con boost :: shared_ptr http://stackoverflow.com/questions/13823300/pointer-to-boostthread http://www.boost.org/doc/libs/1_55_0/doc/html/ thread/thread_management.html – fox

+2

Perché stai usando 'new' per il thread in primo luogo? Sembra abbastanza inutile. – juanchopanza

+0

dovresti uscire da quel thread con garbo, quindi unirti per aspettare che finisca, in questo modo: Car :: ~ Car() {m_runningThreadPtr-> join(); elimina m_runningThreadPtr; } – wshcdr

risposta

1

Per impostazione predefinita il distruttore chiamerà terminate() di uccidere il filo se è ancora in esecuzione, se questo è sicuro o meno dipende da ciò che il filo sta facendo in quel momento. È possibile chiamare join() prima di eliminarlo se si desidera attendere il completamento del thread e utilizzare una sorta di sistema di sincronizzazione (anche solo un flag globale) che dice al thread di uscire.

+0

Si noti che questo è 'boost :: thread', non' std :: thread'. Chiamerà 'detach', non' terminate'. Pertanto, l'eliminazione dell'oggetto thread è "innocua" (sebbene non sia consigliabile) poiché il thread separato non verrà eliminato. – Damon

0

Non eliminarlo. Avere il thread cancellare se stesso quando fatto.

+1

Questo potrebbe essere pericoloso a seconda dell'API. Per esempio. il distruttore dell'oggetto thread potrebbe richiamare 'join()' su se stesso, causando effettivamente un deadlock. –

0

Il programma è terminato quando non c'è più codice da eseguire. I tuoi thread sono ancora in esecuzione? Allora perché pensi che il tuo programma sia finito?

Quindi, è ragionevole presumere che i thread siano effettivamente fatti. Ciò significa che è possibile chiamare .join() sul thread, dopodiché è possibile chiamare delete.

1

Dipende dal tipo di comportamento che stai cercando.

Se si desidera eliminare l'oggetto e interromperne il thread di proprietà e quindi eliminare l'oggetto thread, è necessario disporre di un flag di stop che il thread controlla di volta in volta. Nel distruttore, devi impostare il flag di stop e quindi chiamare join() sul thread. Una volta che ritorna, puoi tranquillamente cancellare il puntatore.

Se, al contrario, si desidera eliminare l'oggetto e far sì che il thread vada avanti da solo fino a quando non termina, è necessario un meccanismo più intelligente, come alla fine della funzione thread, la pubblicazione sul main thread della tua applicazione un callback che chiama join() sulla tua discussione e poi delete s it. Per questo, ovviamente, avrai bisogno di avere nella tua discussione un puntatore al tuo oggetto thread.

EDIT Nel caso di boost::thread, spicca semplicemente nel suo distruttore, così per la seconda opzione è possibile eliminare quando hai finito. È importante notare, tuttavia, che questo non funzionerà con il distruttore di std::thread, che in tal caso interromperà il programma. Ma poi puoi anche chiamare manualmente detach() e poi delete. Quindi devi davvero guardare l'API che stai utilizzando.

Problemi correlati