2013-07-12 14 views
10

Provo a sviluppare un threadpool in C++ e mi chiedo se è meglio restituire() il thread nel loop principale del thread di lavoro o attendere una variabile di condizione:Implementazione del threadpool: condition_variables vs. yield()

void worker_thread(void) 
{ 
    // this is more or less pseudocode 
    while(!done) 
    { 

     if(task_available) 
      run_task(); 
     else 
      std::this_thread::yield(); 
    } 
} 

contro

void worker_thread(void) 
{ 
    // this is more or less pseudocode 

    std::unique_lock<std::mutex> lk(mutex_); 
    while(!done) 
    { 

     if(task_available) 
      run_task(); 
     else 
      condition_.wait(lk); 
    } 
} 

Tutte le idee? Ci saranno differenze di prestazioni tra entrambe le versioni?

risposta

7

se i thread nel pool di thread sono costantemente alimentati con attività e è necessario un tempo di risposta rapido, quindi la resa è ciò che si desidera, ma il rendimento brucerà i cicli cpu indipendentemente dal thread in attesa. in caso contrario, è possibile utilizzare l'approccio condizionale, i thread dormiranno fino a quando un compito è pronto (si noti però, un condizionale può riattivare un thread, anche se non è stato inviato alcun segnale pronto), il tempo di risposta potrebbe essere più lento, ma non lo si bruciare cicli di CPU.

Vorrei raccomandare l'approccio condizionale e se il tempo di reazione è troppo lento, passare alla resa.

+1

Come viene implementato l'approccio condizionale? Hanno un simile meccanismo di attesa che il worker_thread sopra? Il rendimento – headmyshoulder

+1

fa sì che il thread chiamante esegua l'esecuzione su un altro thread pronto per essere eseguito sul processore corrente (vedere SwitchToThread per Windows). –

+0

per condizionali, vedere pthread_cond_wait. quindi fa sì che il thread entri in uno stato di sospensione finché non viene attivato il condizionale (come un evento su Windows) –

5

Il costo di un interruttore di filo è lo stesso in entrambi i casi. Per quanto riguarda l'eventuale utilizzo di variabili di polling o di condizione, quest'ultimo può appoggiare il processore eliminando il thread fino a quando non c'è davvero qualcosa da fare. Ciò si traduce in un minore utilizzo della CPU. Il metodo di polling consentirà al thread di tornare e "riprovare", eseguendo in modo efficace la CPU indefinitamente.

Vale la pena notare che esistono alcune applicazioni che preferiscono il polling, ad esempio quando task_available è falso per un periodo di tempo molto breve (ad esempio, di solito c'è lavoro da fare). In tal caso, vorrai effettuare il sondaggio task_available in un ciclo con un contatore; restituisce il thread solo quando il contatore supera una soglia.