2010-06-08 7 views
9

Sembra che Linux non implementa pthread_suspend e continui, ma ho davvero bisogno di em.linux pthread_suspend

Ho provato cond_wait, ma è troppo lento. Il lavoro di threading esegue per lo più in 50us ma occasionalmente esegue verso l'alto di 500ms. Il problema con cond_wait è duplice. Il blocco mutex sta prendendo tempi comparabili alle micro seconde esecuzioni e non ho bisogno di essere bloccato. In secondo luogo, ho molti thread di lavoro e non voglio davvero creare variabili di condizione N quando hanno bisogno di essere risvegliati.

Io so esattamente quale thread è in attesa di quale lavoro e potrei semplicemente pthread_continue quel thread. Un thread sa quando non c'è più lavoro e può facilmente pthread_suspend se stesso. Ciò non userebbe il blocco, eviterebbe la fuga precipitosa e sarebbe più veloce. Il problema è .... no pthread_suspend o _continue.

Qualche idea?

+0

Invia pezzi di lavoro più grandi ai thread, in modo che il costo del blocco diventi un overhead% inferiore? (I thread trascorrono più tempo a lavorare e meno tempo a delegare il lavoro?) – Thanatos

+0

Il lavoro è grande ... a volte. Non posso dirlo finché non lo provi. E ho spedito il lavoro in un modo che non ha bisogno di bloccare affatto ... se non ho capito il modo ottimale a basso costo di sospendere e riattivare i thread senza bloccare ... cond_wait blocca un mutex per ogni thread che è risvegliato. Inoltre non ti permette di svegliare solo un thread. Beh, potrei fare una condizione per ogni filo .... argh ... Ci dev'essere un modo migliore. cond_wait sembra adatto per un thread utente gui, ma non per le transazioni ad alta velocità. – johnnycrash

+0

Domani guarderò il codice sorgente per cond_wait oltre a perf per test i metodi pipe e pipe vs cond wait. – johnnycrash

risposta

7

Attendere il thread per un segnale specifico.

Utilizzare pthread_sigmask e sigwait.

+0

+1 per una risposta promettente . Lo metterò alla prova stasera e ti darò la risposta se funziona. Grazie! – johnnycrash

+0

Hai dimenticato di menzionare DEVE usare 'pthread_kill' per segnalare un thread specifico, altrimenti non puoi prevedere quale thread sta per riprendere. – jweyrich

+3

Abbiamo eseguito test su questo metodo e risulta che siamo riusciti a dormire e a riattivare i thread con una velocità 40 volte maggiore rispetto all'utilizzo di pthread_cond_wait. – johnnycrash

0

Mi sembra che una soluzione del genere (ovvero, utilizzando "pthread_suspend" e "pthread_continue") sia inevitabilmente vivace.

Un intervallo di tempo arbitrario può intercorrere tra il lavoro di rifinitura del thread di lavoro e la decisione di sospendere se stesso e la sospensione effettivamente in atto. Se il thread principale decide durante quel periodo che quel thread worker dovrebbe funzionare di nuovo, il "continue" non avrà alcun effetto e il thread worker si sospenderà indipendentemente.

(Si noti che questo non si applica ai metodi di sospensione che consentono di accodare "continua", come i metodi sigwait() e read() menzionati in altre risposte).

+0

Si noti che i segnali sono in coda (almeno su NPTL). – jweyrich

+2

@jweyrich: Aye, puoi farlo con i segnali, dal momento che 'sigwait()' fa effettivamente un blocco atomico-wait-block. – caf

+0

Quando il dispatcher aggiunge lavoro alla coda di lavoro circolare, controllerà la coda circolare sospesa corrispondente. Un thread sospeso con lo stesso indice del lavoro verrà riattivato. Il filo del risveglio cancella la bandiera sospesa. Di tanto in tanto, il dispatcher analizzerà la coda sospesa alla ricerca di thread che non si sono svegliati (la gara) e li segnalerà di nuovo. Al termine dell'elaborazione, è necessario ripetere la scansione sospesa (magari con un sonno di 1 ms) fino a quando tutti i thread non si attivano e si completano. Dal momento che le condizioni di gara sono rare, stima che per 1/100 le transazioni sarà necessaria la scansione extra alla fine. – johnnycrash

2

Avere il blocco di thread su una pipe leggere. Quindi invia i dati attraverso la pipe. I thread si risveglieranno come risultato dell'arrivo dei dati che devono elaborare. Se i dati sono molto grandi, basta inviare un puntatore attraverso la pipe.

Se dati specifici devono passare a thread specifici è necessario un tubo per thread. Se qualsiasi thread può elaborare qualsiasi dato, tutti i thread possono bloccarsi sulla stessa pipe e risvegliano il round robin.

0

Può essere provate un'opzione di pthread_cancel ma attenzione, se tutte le serrature per essere rilasciato, Leggere la pagina man per identificare annullare stato

0

Perché ti interessa quale thread fa il lavoro? Sembra che tu abbia progettato te stesso in un angolo e ora hai bisogno di un trucco per tirartene fuori. Se lasci che qualunque thread sia già in esecuzione esegui il lavoro, non avresti bisogno di questo trucco e avresti bisogno di un minor numero di interruttori di contesto.

+0

C'è un pool di thread. C'è anche un elenco di thread che attendono il completamento del lavoro o sono inattivi. Se il nuovo elemento di lavoro sembra essere una dipendenza per un thread in attesa, mi sveglio quel thread; altrimenti, mi sveglio un thread inattivo. Il segnale mi consente di indirizzare un particolare thread dormiente o il primo thread inattivo. Ho arrotolato la mia coda di lavoro che utilizzava l'atomica invece dei mutex e delle variabili di condizione. Ciò manteneva il sovraccarico sufficientemente basso da mantenere le prestazioni anche se gli elementi di lavoro richiedevano microsecondi. Ho solo bisogno di essere in grado di dormire un thread occasionalmente come un mutex o cv. – johnnycrash

+0

@johnnycrash Sembra un cattivo design. Perché un thread specifico è in attesa di una cosa specifica? Puoi aspettare che X accada prima di fare Y senza avere un thread in attesa. Quando X accade, allora organizzi in modo che * qualsiasi * thread possa fare Y. Il tuo design ti costringe a risolvere il problema di risvegliare thread specifici e quindi obbliga commutazioni extra del contesto e penalità di scheduler/cache perché quel thread potrebbe essere inefficiente da eseguire in quel momento . –