Cada vez que se utiliza una arquitectura basada en eventos, se requiere tener un mecanismo único para informar la finalización del evento. En Linux, si uno está usando archivos, se requiere que use algo de la familia de selección o encuesta, lo que significa que uno está atascado con el uso de una canalización para iniciar todos los eventos no relacionados con archivos.
Editar :Linux tiene eventfd y timerfd. Estos se pueden agregar a su epoll
lista y solía salir del epoll_wait
cuando se activa desde otro subproceso o en un evento de temporizador, respectivamente.
Hay otra opción y son las señales. Uno puede usar fcntl
modificar el descriptor de archivo de modo que se emita una señal cuando el descriptor de archivo se active. El manejador de señales puede enviar un mensaje de archivo listo a cualquier tipo de cola de su elección. Esto puede ser una simple cola impulsada por un semáforo o mutex/condvar. Ya que uno ya no usa select
/poll
, ya no es necesario utilizar una canalización para poner en cola ningún mensaje basado en archivos.
Advertencia de salud:no he probado esto y aunque no puedo ver por qué no funcionará, realmente no sé las implicaciones de rendimiento del signal
acercamiento.
Editar:manipular un mutex en un controlador de señal es probablemente una muy mala idea.
Resolví este problema exacto usando lo que mencionas, pipe() y libevent (que envuelve epoll). El subproceso de trabajo escribe un byte en su tubería FD cuando su cola de salida pasa de vacía a no vacía. Eso activa el subproceso IO principal, que luego puede tomar la salida del subproceso de trabajo. Esto funciona muy bien, en realidad es muy simple de codificar.
Tiene la etiqueta de Linux, así que voy a descartar esto:las colas de mensajes POSIX hacen todo esto, lo que debería cumplir con su solicitud "incorporada", si no con su deseo multiplataforma menos deseado.
La sincronización segura para subprocesos está integrada. Puede hacer que sus subprocesos de trabajo se bloqueen al leer la cola. Alternativamente, los MQ pueden usar mq_notify() para generar un nuevo hilo (o señalar uno existente) cuando hay un nuevo elemento en la cola. Y dado que parece que va a usar select(), el identificador de MQ (mqd_t) se puede usar como un descriptor de archivo con select.