2010-03-28 21 views
11

En una aplicación de Linux estoy usando tuberías para pasar información entre hilos.son tubos posix ligeros?

La idea detrás del uso de tuberías es que puedo esperar varias tuberías a la vez usando la encuesta (2). Eso funciona bien en la práctica, y mis hilos están durmiendo la mayor parte del tiempo. Solo se despiertan si hay algo que hacer.

En el espacio de usuario las tuberías se parecen a dos manejadores de archivos. Ahora me pregunto cuántos recursos usan esas tuberías en el lado del sistema operativo.

Btw: En mi aplicación, solo envío bytes individuales de vez en cuando. Piensa en mis pipas como simples colas de mensajes que me permiten reactivar la recepción de subprocesos, les digo que envíen algunos datos de estado o que finalicen.

+6

Posix especifica la interfaz de la tubería, no la implementación, que es de donde proviene el "peso". –

+0

¿Cuántos canales hay? ¿Cuántos mensajes por segundo? Cientos? Millones? Haga un prototipo simple usando varias tecnologías (cualquier cosa, desde colas de mensajes IPC hasta tuberías, zócalos UNIX, etc.) y compare. –

Respuesta

4

Como está utilizando Linux puede investigar y comparar el rendimiento de pipe con eventfd. Son técnicamente más rápidos y livianos, pero tendrás mucha suerte de ver los avances en la práctica.

http://www.kernel.org/doc/man-pages/online/pages/man2/eventfd.2.html

+0

¡GUAU! Gracias por señalar esto. Estoy usando tuberías para este tipo de cosas, y estoy seguro de que puedo reemplazar al menos la mitad de ellas con eventfd's. La mayoría de las veces todo lo que realmente quiero es señalar un estado a un hilo que está bloqueado en una encuesta. Si eventfd es más liviano, lo usaré. –

7

No, no consideraría que las tuberías son "livianas", pero eso no necesariamente significa que sean la respuesta incorrecta para su aplicación.

Enviar un byte por una tubería requerirá un mínimo de 3 llamadas al sistema (escritura, sondeo, lectura). El uso de una cola en memoria y operaciones pthread (mutex_lock, cond_signal) implica mucho menos sobrecarga. Descriptores de archivos abiertos definitivamente consumen recursos de kernel; es por eso que los procesos generalmente están limitados a 256 archivos abiertos de forma predeterminada (no es que el límite no se pueda expandir cuando corresponda).

Aún así, la solución de tubo/sondeo para comunicación entre hilos también tiene ventajas: particularmente si necesita esperar la entrada de una combinación de fuentes (red + otros hilos).

+0

¿Por qué tomaría 3 llamadas al sistema? una llamada ciega 'write()' se bloqueará si los búferes de la tubería están llenos. si cada hilo solo necesita escuchar su propio conducto, también puede soltar el 'poll()', simplemente esperando que 'read()' tenga éxito – Hasturkun

+2

OP dijo específicamente que está usando poll() para esperar que aparezcan varios pipes un hilo de consumo. –

+0

Tengo que leer y escribir en un archivo (/ dev/ttySxx serie) * y * ser capaz de responder a comandos de otro hilo. El bloqueo está fuera de discusión. Si, por ejemplo, tengo una escritura de 10 megabytes en el serial, no puedo esperar hasta que termine si la aplicación me dice que quiere abortar la transferencia. Por lo tanto, dos archivos no bloqueantes que busco: uno para el puerto serie y otro para recibir comandos. –

1

Mida y sabrá. Los procesos completos con tuberías son lo suficientemente ligeros para muchas aplicaciones. Otras aplicaciones requieren un peso más ligero, como subprocesos OS (pthreads es la opción popular para muchas aplicaciones Unix), o superligero, como un paquete de subprocesos de nivel de usuario que nunca pasa al modo núcleo excepto para manejar E/S. Si bien la única forma de saberlo con certeza es medir, las tuberías probablemente sean lo suficientemente buenas para unas pocas decenas de subprocesos, mientras que probablemente desee subprocesos de nivel de usuario una vez que llegue a unas pocas decenas de miles de subprocesos. Exactamente dónde deben dibujarse los límites usando los códigos de hoy, no lo sé. Si quisiera saber, mediría :-)

+0

Supongo que estoy confundido. Creo que la implementación NPTL de Linux es de nivel kernel. ¿Glibc proporciona una implementación de nivel de usuario además de eso? –

+0

@Wei: Mi error. Editado –

0

También es posible usar socketpair, que es más portátil que eventfd porque es POSIX.

Cuestiones relacionadas