2010-03-28 18 views
11

In un'applicazione linux sto usando pipe per passare informazioni tra thread.sono tubi posix leggeri?

L'idea alla base dell'utilizzo dei tubi è che posso attendere più tubi contemporaneamente utilizzando il polling (2). Funziona bene nella pratica e le mie discussioni dormono la maggior parte del tempo. Si svegliano solo se c'è qualcosa da fare.

Nello spazio utente le pipe hanno lo stesso aspetto di due handle di file. Ora mi chiedo quante risorse usano queste pipe sul lato del sistema operativo.

Btw: Nella mia applicazione invio solo singoli byte ogni ora e poi. Pensa ai miei tubi come a semplici code di messaggi che mi consentono di riattivare i thread riceventi, dire loro di inviare alcuni dati di stato o di terminare.

+6

Posix specifica l'interfaccia del tubo, non l'implementazione, da cui proviene il "peso". –

+0

Quanti canali? Quanti messaggi al secondo? Centinaia? Milioni? Realizza un semplice prototipo utilizzando diverse tecnologie (qualsiasi cosa, dalle code dei messaggi IPC alle pipe ai socket UNIX ecc.) E confronta. –

risposta

4

Poiché si utilizza Linux, è possibile esaminare e confrontare le prestazioni di pipe con eventfd. Sono tecnicamente più veloci e leggeri, ma sarai molto fortunato a vedere i guadagni nella pratica.

http://www.kernel.org/doc/man-pages/online/pages/man2/eventfd.2.html

+0

WOW! Grazie per averlo indicato. Sto usando pipe per questo genere di cose, e sono sicuro di poter sostituire almeno la metà di esse usando eventfd. Il più delle volte tutto ciò che voglio veramente è segnalare uno stato a un thread che è bloccato nel sondaggio. Se eventfd è più leggero lo userò. –

7

No, non considererei i tubi "leggeri", ma ciò non significa necessariamente che siano la risposta sbagliata per l'applicazione.

L'invio di un byte su una tubazione richiede un minimo di 3 chiamate di sistema (scrittura, polling, lettura). L'uso di una coda in memoria e operazioni pthread (mutex_lock, cond_signal) comporta un sovraccarico molto minore. I descrittori di file aperti consumano sicuramente risorse del kernel; è per questo che i processi sono in genere limitati a 256 file aperti per impostazione predefinita (non che il limite non possa essere espanso laddove appropriato).

Ancora, la soluzione pipe/poll per la comunicazione tra thread presenta anche vantaggi: in particolare se è necessario attendere input da una combinazione di fonti (rete + altri thread).

+0

Perché occorrerebbero 3 chiamate di sistema? una blind 'write()' call si bloccherà se i buffer della pipe sono pieni. se ogni thread ha solo bisogno di ascoltare la propria pipe, puoi anche rilasciare 'poll()', semplicemente aspettando 'read()' per riuscire – Hasturkun

+2

OP in particolare ha detto che sta usando poll() per aspettare pipe multiple da un filo del consumatore. –

+0

Devo leggere e scrivere su un file (/ dev/ttySxx serial) * e * essere in grado di rispondere ai comandi da un altro thread. Il blocco è fuori questione. Se per esempio ho una scrittura da 10 megabyte sul seriale, non vedo l'ora che sia finita se l'applicazione mi dice che vuole interrompere il trasferimento. Quindi due file non bloccanti per i quali eseguo il polling: uno per la porta seriale e uno per ricevere i comandi. –

1

Misura e lo saprai. I processi completi con tubi sono sufficientemente leggeri per molte applicazioni. Altre applicazioni richiedono qualcosa di più leggero, come i thread del sistema operativo (i pthread sono la scelta popolare per molte app Unix), o superlightweight, come un pacchetto di thread a livello utente che non entra mai in modalità kernel eccetto per gestire l'I/O. Mentre l'unico modo per sapere con certezza è quello di misurare, i tubi sono probabilmente abbastanza buoni per un massimo di poche decine di thread, mentre probabilmente si vogliono i thread a livello utente una volta che si arriva a qualche decina di migliaia di thread. Esattamente dove i confini dovrebbero essere disegnati usando i codici di oggi, non lo so. Se volessi saperlo, misurerei :-)

+0

Immagino di essere confuso. Penso che l'implementazione NPTL di Linux sia a livello di kernel. Glibc fornisce un'implementazione a livello di utente in aggiunta? –

+0

@Wei: Il mio errore. Modificato. –

0

Si potrebbe anche usare socketpair, che è più portabile di eventfd perché è POSIX.