2015-06-23 7 views
5

C'è una cosa su std::thread che non capisco: perché il costruttore di std::thread accetta la funzione per l'esecuzione di rvalue?Perché la funzione std :: thread assume l'esecuzione per valore?

In genere, voglio eseguire un Functor con alcuni membri su un altro thread. Come questo:

struct Function 
{ 
    void operator() (/* some args */) 
    { 
     /* some code */ 
    } 

    /* some members */ 
} 


void run_thread() 
{ 
    Functor f(/* some data */); 
    std::thread thread(f, /* some data */); 

    /* do something and wait for thread to finish */ 
} 

Con implementazione corrente di std::thread devo essere sicuro che il mio oggetto sta attuando la semantica move. Non capisco perché non posso passarlo per riferimento.

La domanda in più è: cosa significa riferirsi alla funzione per valore? Espressione Lambda?

+4

Il costruttore 'std :: thread' ha la funzione di inoltro di riferimento. –

+0

L'oggetto non ha bisogno di implementare la semantica del movimento. Se lo spostamento non è supportato, si limita a ricorrere alla copia. – nwp

+0

@nwp: cosa succede se l'oggetto ha cancellato il costruttore di copie? Perché è necessaria la copia? –

risposta

6

Nel metodo run_thread f è una variabile automatica. Ciò significa che nella parte inferiore dello scope f verrà distrutto. Si afferma che si "aspetterà il completamento del thread" ma il sistema di compilazione/runtime non lo sa! Si deve supporre che f verrà eliminato, probabilmente prima che il thread che si suppone chiami il suo metodo abbia la possibilità di avviarsi.

Copiando (o spostando) il f, il sistema di runtime ottiene il controllo della durata della sua copia di f e può evitare alcuni problemi davvero difficili, difficili da debug.

3

std::reference_wrapper esporrà un oggetto operator() all'oggetto spostato. Se si è disposti a eseguire la manutenzione a vita manuale, std::thread t(std::ref(f)); verrà eseguito per riferimento come f.

Ovviamente nel codice, questo induce un comportamento indefinito poiché non hai gestito correttamente le durate.


Infine, ricordiamo che cruda thread è un povero strumento "codice cliente". async è un tocco migliore, ma in realtà si desidera una coda di attività con packaged_task se future s e variabili di condizione. C++ 11 ha aggiunto abbastanza supporto per il threading per scrivere un sistema di threading decente, ma fornisce primitive, non buoni strumenti "client code".

In un programma di giocattoli potrebbe essere sufficiente.

Problemi correlati