2009-08-05 37 views
19

He oído que mezclar bifurcación y subprocesamiento en un programa podría ser muy problemático, a menudo como resultado de un comportamiento misterioso, especialmente cuando se trata de recursos compartidos, como bloqueos, tuberías, descriptores de archivos. Pero nunca entiendo completamente cuáles son exactamente los peligros y cuándo pueden suceder. Sería genial si alguien con experiencia en esta área pudiera explicar un poco más en detalle cuáles son las dificultades y qué debe ser cuidado al programar en un entorno de este tipo.tenedor en el programa multiproceso

Por ejemplo, si quiero escribir un servidor que reúna datos de varios recursos diferentes, una solución que he pensado es tener el servidor genera un conjunto de hilos, cada popen para llamar a otro programa para hacer el real trabaje, abra las tuberías para recuperar los datos del niño. Cada uno de estos subprocesos responde por su propio trabajo, sin intercambio de datos en b/w, y cuando se recopilan los datos, el hilo principal tiene una cola y estos subprocesos de trabajo simplemente pondrán el resultado en la cola. ¿Qué podría salir mal con esta solución?

No limite su respuesta simplemente "respondiendo" mi escenario de ejemplo. Cualquier sugerencia, solución alternativa o experiencia que no esté relacionada con el ejemplo pero que sea útil para proporcionar un diseño limpio sería genial. ¡Gracias!

+0

aquí es una [buena lectura] (http://thorstenball.com/blog/2014/10/13/why-threads-cant-fork/) con más detalles sobre el tema - –

Respuesta

0

Es realmente bastante simple. Los problemas con múltiples hilos y procesos siempre surgen de los datos compartidos. Si no hay datos compartidos, entonces no puede haber problemas posibles.

En su ejemplo, los datos compartidos son la cola propiedad del hilo principal; aquí se presentarán posibles conflictos o condiciones de carrera. Los métodos típicos para "resolver" estos problemas implican esquemas de bloqueo: un hilo de trabajo bloqueará la cola antes de insertar cualquier dato, y el hilo principal bloqueará la cola antes de eliminarla.

+0

¿Los metadatos malloc cuentan como "datos compartidos"? :) – bdonlan

+0

No sé, pero normalmente sus librerías estándar están escritas de tal manera que no tienen subprocesos (a veces debe seleccionar versiones seguras para subprocesos). Depende de cuál sea su definición de datos compartidos y cuál es el impacto. –

+0

a menudo, no podemos evitar tener datos compartidos. como tuberías, descriptores de archivos, etc. Siempre se comparten en el tenedor. Ahora bajo linux, uno puede establecer el indicador O_CLOEXEC para que un fd pueda cerrarse al bifurcar (supongo que lo que significa es cerrar el fd en el espacio de direcciones del niño), aunque no sé si eso ayudaría si agregamos hilos en ? p.ej. ¿y si abro tuberías en un hilo y tenedor? ¿y si otro hilo también tiene tenedor? ¿Qué niño podrá ver la tubería? – jimx

16

El problema con la bifurcación cuando hay algunos subprocesos en ejecución es que la horquilla solo copia el estado de la CPU del único subproceso que lo llamó. Es como si todos los otros hilos acabaran de morir, instantáneamente, donde sea que estén.

El resultado de esto es que los bloqueos no se liberan, y los datos compartidos (como el montón malloc) pueden estar dañados.

pthread sí ofrece una función pthread_atfork - en teoría, usted podría tomar todas las cerraduras en el programa antes de que se bifurcan, liberarlos después, y quizá salir con vida - pero es arriesgado, porque siempre se puede perder uno. Y, por supuesto, las pilas de los otros hilos no serán liberadas.

+0

¿Puede explicar un poco qué significa 'no se liberan los bloqueos'? Desde la perspectiva infantil ¿no? Entonces, ¿el niño nunca puede adquirir un candado? – jimx

+0

Correcto. La horquilla clona todas las cerraduras mientras todavía están en el estado bloqueado. – bdonlan

Cuestiones relacionadas