2010-02-11 2 views
7

Lo scenario corrente è epoll_wait su un paio di fds e una coda di possibili messaggi in arrivo, vorrei che il ciclo sotto epoll_wait fosse eseguito su evento IO o su nuovo messaggio.
Ways so:Interrompere epoll_wait con un evento non-IO, nessun segnale

  • Utilizzare un timeout msec time e controllare la coda prima cosa al ciclo
  • Utilizzare il self-pipe trick dal codice della coda quando i messaggi saranno disponibili
  • Interrompere lo syscall con un segnale standard
  • Usa epoll_pwait e perfezionare al punto precedente

Nessuno dei punti postato sopra soddisfare me enoug e mi stavo chiedendo se ci sono altri metodi che non ho trovato.
Le ragioni sono:

  • segnali sono qualcosa da evitare sul codice multi-threaded e non sono molto affidabili
  • Timeout uno rimuove parte del beneficio della epoll, solo svegliarsi con eventi
  • Self-pipe sguardi trucco l'approccio migliore per il momento, ma ancora troppo foglio di accensione

idee?

risposta

17

È possibile utilizzare uno eventfd che è effettivamente la stessa cosa del trucco di autotubo tranne che con un numero inferiore di descrittori di file e meno numero di piastre (glibc ha ad esempio le funzioni eventfd_read/write).

+0

Ho usato eventfd con successo quando solo un thread è in attesa di un epollfd, ma che dire di più thread stanno aspettando lo * stesso * epollfd? è utile anche in questo caso? se é cosi, come? –

1

Hai elencato gli eventi che possono svegliare epoll, quindi la domanda diventa davvero: "Come faccio a ridurre il boilerplate per il trucco self-pipe?"

La risposta a questa domanda dipende molto dal codice, dalla lingua e da ciò che si sta tentando di fare. Presumo che tu abbia una discussione che elabora I/O e vuoi fare altro lavoro in quel thread mentre non ci sono I/O pronti. Nel codice che gestisce il ciclo epoll, può avere un handle interno che viene esposto ad altre parti del sistema come una funzione "sveglia" o una funzione "invia lavoro".

Ci sono librerie che fanno questo, ad esempio boost.asio per C++. Tuttavia, non è difficile scrivere da soli se stai mirando a epoll, e la quantità di codice boilerplate dovrebbe essere minima una volta che hai una classe/modulo/qualsiasi cosa riguardi il ciclo epoll.