¿Cuál es el mejor equivalente de epoll/kqueue/select en Windows?
-
09-06-2019 - |
Pregunta
¿Cuál es la mejor función de notificación de eventos de E/S de Windows?
Por mejor me refiero a algo que...
- no tiene un límite en la cantidad de descriptores de archivos de entrada
- funciona en todos los descriptores de archivos (archivos de disco, sockets, ...)
- proporciona varios modos de notificación (activado por flanco, activado por límite)
Solución
En Windows, las operaciones asíncronas se realizan mediante operación de archivo, no mediante descriptor.Hay varias formas de esperar a que las operaciones de archivos se completen de forma asincrónica.
Por ejemplo, si desea saber cuándo hay datos disponibles en un socket de red, emita una solicitud de lectura asíncrona en el socket y cuando se complete, los datos estaban disponibles y se recuperaron.
En Win32, las operaciones asíncronas utilizan el OVERLAPPED
estructura para contener el estado sobre una operación IO pendiente.
- Asociar los archivos con un Puerto de finalización de E/S y enviar solicitudes de IO asíncronas.Cuando se completa una operación, colocará un mensaje de finalización en la cola que sus subprocesos de trabajo pueden esperar y recuperar a medida que llegan.También puede poner mensajes definidos por el usuario en la cola.No hay límite en cuanto a la cantidad de archivos o mensajes en cola que se pueden usar con un puerto de finalización.
- Envíe cada operación de IO con un evento.El evento asociado con una operación se señalará (satisfará una espera) cuando se complete.Usar
WaitForMultipleObjects
esperar todos los eventos a la vez.Esto tiene la desventaja de que sólo se puede esperarMAXIMUM_WAIT_OBJECTS
objetos a la vez (64).También puede esperar otros tipos de eventos al mismo tiempo (terminación de proceso/hilo, mutex, eventos, semáforos) - Usar una grupo de hilos.El grupo de subprocesos puede tomar un número ilimitado de objetos y operaciones de archivos para esperar y ejecutar un función definida por el usuario al finalizar cada uno.
- Usar
LeerArchivoEx
yWriteFileEx
hacer cola Llamadas a procedimientos asincrónicos (APC) al hilo de llamada ySleepEx
(oWaitFor{Single|Multiple}ObjectsEx
) conAlertable TRUE
para recibir un mensaje de notificación para cada operación cuando se complete.Este método es similar a un puerto de finalización de IO, pero solo funciona para un subproceso.
El kernel de Windows NT no hace distinción entre socket, archivo de disco, tubería, etc.operaciones de archivos internamente:Todas estas opciones funcionarán con todos los tipos de archivos.
Otros consejos
libuv
libuv
ofrece E/S eventos para Unix y Windows y tiene soporte para sockets, archivos y canalizaciones.Es la capa de plataforma de Node.js.
Más detalles están en: http://nikhilm.github.io/uvbook/introduction.html
Hasta donde yo sé, todavía no hay ninguno.Un amigo y yo estamos trabajando en una implementación de epoll de Windows de código abierto (enlace a continuación), pero tenemos problemas para descubrir cómo hacer que funcione igual que la implementación de Linux.
Obstáculos actuales:
- En Linux, los descriptores de archivos y los descriptores de sockets son intercambiables, pero en Windows no lo son.Ambos deben ser compatibles con una implementación de epoll.
- En Windows es bastante complicado obtener eventos del kernel...Así es como funciona epoll en Linux.Suponemos que un programa que utilice nuestra biblioteca epoll multiplataforma se ejecutará notablemente más lento en Windows que en Linux.
Intentaré volver y actualizar esta publicación a medida que avancemos con el proyecto.
La función select() es POSIX y se puede utilizar en Windows, incluidos "winsock.h" o "winsock2.h".