Come leggere più descrittori di file utilizzando epoll_select con EPOLLET?
Domanda
man epoll:
The suggested way to use epoll as an edge-triggered (EPOLLET) interface is as follows:
i with nonblocking file descriptors; and
ii by waiting for an event only after read(2) or write(2) return EAGAIN.
Immaginiamo di avere due FDS: la prima è passiva, i dati disponibili solo a volte, la seconda è attiva, i dati solo a volte non disponibili
.epoll_wait restituito che siamo in grado di leggere entrambi. Leggiamo {il primo, rispetto al secondo} in un ciclo (senza chiamate a epoll_wait a causa di esso può improvvisamente bloccare, mentre i dati sono ancora disponibili).
Ora il primo descrittore di file restituito EAGAIN sulla lettura.
Cosa fare?
- Se andiamo a leggere il secondo fd in un ciclo (senza chiamate a epoll_wait), possiamo mancare che i dati sono resi disponibili sul primo fd. E 'solo leggere e leggere e leggere senza EAGAIN.
- Se ci sarà "consultare" con epoll_wait prima di ogni lettura dalla seconda fd, epoll_wait può improvvisamente bloccare a causa di nulla è cambiato dalla chiamata precedente (dati non ancora disponibile sul primo FD e ancora disponibile sul secondo FD).
Come continuare l'elaborazione del secondo FD, ma senza dimenticare la prima FD?
Aggiornamento: Trovato ancora una cosa: l'uomo epoll_wait:
while specifying timeout equal to zero makes epoll_wait() to return immediately even if no events are available
Con questo posso enumerare eventi per DF, anche se non ci sono eventi.
Soluzione
Se FD2 è costantemente leggibili si potrebbe considerare che epoll non è appropriato per questo. Potrebbe valere la pena di filatura fuori un filo solo per sedersi e lo lesse.
Altrimenti, leggere FD2 in un ciclo finché viene scaricata ma nel ciclo averlo tenta di leggere FD1 volta ogni X volte attraverso. Se FD1 ha dati, leggerlo. Se non ti basta avere EAGAIN, azzerare il contatore X e tornare alla lettura FD2. Quando entrambi sono scariche si torna al epoll_wait.
Qualcosa di simile:
count = 1;
while (true)
{
read fd2;
if (EAGAIN)
break;
else
process data;
count--;
if (! count)
{
while (true)
{
read fd1;
if (EAGAIN)
count = 10;
break;
else
process data;
}
}
}