2013-07-03 16 views
5

Sto scrivendo una classe del pool di thread in C++ che riceve le attività da eseguire in parallelo. Voglio che tutti i core siano occupati, se possibile, ma a volte alcuni thread sono inattivi perché sono bloccati per un periodo di sincronizzazione. Quando ciò accade vorrei iniziare una nuova discussione, in modo che ci siano sempre all'incirca tanti thread quanti sono i core della CPU. A questo scopo ho bisogno di un modo per scoprire se un determinato thread è sveglio o sta dormendo (bloccato). Come posso scoprirlo?C'è un modo per scoprire se un thread è bloccato?

Preferirei utilizzare la libreria standard C++ 11 o boost per scopi di portabilità. Ma se necessario, utilizzerei anche WinAPI. Sto usando Visual Studio 2012 su Windows 7. Ma davvero, mi piacerebbe avere un modo portatile per farlo.

Preferibilmente questo thread-pool dovrebbe essere in grado di dominare casi come

MyThreadPool pool; 
for (int i = 0; i < 100; ++i) 
    pool.addTask(&block_until_this_function_has_been_called_a_hundred_times); 
pool.join(); // waits until all tasks have been dispatched. 

dove la funzione block_until_this_function_has_been_called_a_hundred_times() blocchi fino 100 fili hanno chiamato. A questo punto tutti i thread dovrebbero continuare a funzionare. Un requisito per il pool di thread è che non dovrebbe deadlock a causa di un numero troppo basso di thread nel pool.

+0

Si potrebbe misurare l'utilizzo della CPU al momento, suppongo. Ma a meno che i blocchi non siano molto lunghi (è possibile mantenere le statistiche su "per quanto tempo dormo" se si dispone di un wrapper per i blocchi), probabilmente sarà necessario più tempo per iniziare un nuovo thread rispetto al thread bloccato. Non sono a conoscenza di alcun modo standard per farlo. –

+0

Cosa intendi per bloccato? Se alcuni dei tuoi thread sono inattivi perché sono bloccati, come fa l'avvio di un altro thread, non sarà inattivo in attesa della stessa risorsa dei thread esistenti? Come dice @MatsPetersson, puoi misurare i tempi di inattività dei tuoi thread, ma forse devi misurare il throughput della tua risorsa per mantenere i tuoi thread più occupati possibile. – dwxw

+0

Perché preoccuparsi? Assicurati che il pool, o qualsiasi altra cosa, abbia un numero sufficiente di thread aggiuntivi. –

risposta

2

Utilizzare Boost Asio. Ha una propria struttura di gestione e programmazione del pool di thread. L'idea di base è di inviare le attività all'oggetto utilizzando il metodo post() e chiamare run() da tutti i thread di tutti i core della CPU che si hanno. È necessario creare un oggetto work mentre il calcolo è in esecuzione per evitare che i thread si interrompano se non hanno abbastanza processi.

La cosa importante di Asio è di non utilizzare mai chiamate di blocco. Per le chiamate I/O, utilizzare le chiamate asincrone degli oggetti I/O di Asio. Per la sincronizzazione, utilizzare gli oggetti strand anziché i mutex. Se si inviano funzioni al servizio io che è racchiuso in un filamento, si assicura che in qualsiasi momento al massimo si esegua un'attività che appartiene a un determinato filamento. Se c'è un conflitto, l'attività rimane nella coda degli eventi di Asio invece di bloccare un thread funzionante.

C'è uno svantaggio di utilizzare la programmazione asincrona però. È molto più difficile leggere un codice che è disseminato in più chiamate asincrone rispetto a uno con un chiaro flusso di controllo. Dovresti esserne a conoscenza quando progetti il ​​tuo programma.

2

Aggiungi una struttura al tuo gruppo di thread per una discussione per dire "Sono bloccato" e quindi "Non sono più bloccato". Prima di ogni azione di blocco significativa (vedi sotto per quello che intendo con quello) segnale "I'm blocked", e quindi "I'm is longer blocked" in seguito.

Che cosa costituisce una "significativa azione di blocco"? Certamente non un semplice mutex lock: i mutex dovrebbero essere mantenuti solo per un breve periodo di tempo, quindi il blocco su un mutex non è un grosso problema. Voglio dire le cose come:

  • attesa di I/O per completare
  • In attesa di un altro compito piscina per completare
  • In attesa di dati su un coda condivisa

e altri eventi simili.

+0

Grazie per aver reso la mia risposta più completa e strutturata :) – Dennis