Qual è il miglior equivalente epoll/kqueue/select su Windows?
-
09-06-2019 - |
Domanda
Qual è la migliore funzionalità di notifica degli eventi I/O di Windows?
Per migliore intendo qualcosa che...
- non ha un limite al numero di descrittori di file di input
- funziona su tutti i descrittori di file (file su disco, socket, ...)
- fornisce varie modalità di notifica (attivato dal limite, attivato dal limite)
Soluzione
In Windows, le operazioni asincrone vengono eseguite tramite operazioni sui file, non tramite descrittore.Esistono diversi modi per attendere il completamento delle operazioni sui file in modo asincrono.
Ad esempio, se desideri sapere quando i dati sono disponibili su un socket di rete, invia una richiesta di lettura asincrona sul socket e al termine, i dati erano disponibili e sono stati recuperati.
In Win32, le operazioni asincrone utilizzano il file OVERLAPPED
struttura per contenere lo stato di un'operazione di I/O in sospeso.
- Associare i file con un file Porta di completamento IO e inviare richieste di I/O asincrone.Quando un'operazione viene completata, verrà inserito un messaggio di completamento nella coda su cui i thread di lavoro potranno attendere e recuperare non appena arrivano.È inoltre possibile inserire in coda i messaggi definiti dall'utente.Non esiste alcun limite al numero di file o messaggi in coda che possono essere utilizzati con una porta di completamento
- Invia ogni operazione di I/O con un evento.L'evento associato ad un'operazione verrà segnalato (soddisfare un'attesa) al suo completamento.Utilizzo
WaitForMultipleObjects
attendere tutti gli eventi contemporaneamente.Questo ha lo svantaggio di poter solo attendereMAXIMUM_WAIT_OBJECTS
oggetti contemporaneamente (64).Puoi anche attendere altri tipi di eventi contemporaneamente (terminazione di processi/thread, mutex, eventi, semafori) - Usare un pool di thread.Il pool di thread può richiedere un numero illimitato di oggetti e operazioni sui file in attesa ed eseguire a funzione definita dall'utente al termine ciascuno.
- Utilizzo
LeggiFileEx
EWriteFileEx
fare la fila Chiamate di procedura asincrona (APC) al thread chiamante eSleepEx
(OWaitFor{Single|Multiple}ObjectsEx
) conAlertable TRUE
per ricevere un messaggio di notifica per ogni operazione una volta completata.Questo metodo è simile a una porta di completamento IO, ma funziona solo per un thread.
Il kernel di Windows NT non fa distinzione tra socket, file su disco, pipe, ecc.operazioni sui file internamente:tutte queste opzioni funzioneranno con tutti i tipi di file.
Altri suggerimenti
libuv
libuv
offre I/O con eventi per Unix e Windows e supporta socket, file e pipe.È il livello della piattaforma di Node.js.
Maggiori dettagli sono su: http://nikhilm.github.io/uvbook/introduction.html
Non ce n'è ancora uno, per quanto ne so.Io e un amico stiamo lavorando su un'implementazione epoll di Windows open source (link sotto) ma stiamo riscontrando problemi nel capire come farlo funzionare allo stesso modo dell'implementazione Linux.
Ostacoli attuali:
- In Linux, i descrittori di file e i descrittori di socket sono intercambiabili, ma in Windows non lo sono.Entrambi devono essere compatibili con un'implementazione epoll.
- In Windows è piuttosto complicato ottenere eventi del kernel...ecco come funziona epoll in Linux.Supponiamo che un programma che utilizza la nostra libreria epoll multipiattaforma funzionerà notevolmente più lentamente in Windows rispetto a Linux.
Proverò a tornare e aggiornare questo post man mano che avanziamo con il progetto.
La funzione select() è POSIX e utilizzabile su Windows incluso "winsock.h" o "winsock2.h".