2011-07-11 17 views
7

i tienen una construcción similar a la siguiente:encadenamiento subprocesos Popen adecuadamente

os.mkfifo('pipe.tmp') 
enc = Popen(['encoder', '-i', 'pipe.tmp']) 
cap = Popen(['capture', '-f', 'pipe.tmp']) 

aquí cap es un proceso que normalmente escribe en un archivo (especificado por -f), pero se puede conseguir que arrojan los datos a la pantalla suministrando /dev/stdout como el archivo de salida. de forma similar, enc espera leer de un objeto similar a un archivo, y puedo leerlo desde la tubería suministrando - como entrada. así que en vez de utilizar una tubería con nombre en el sistema operativo, pensé que el archivo especial puede no ser necesario, puedo utilizar un tubo sin nombre como esto ..

cap = Popen(['capture', '-f', '/dev/stdout'], stdout=PIPE) 
enc = Popen(['encoder', '-i', '-'], stdin=cap.stdout) 
cap.stdout.close() 

(nota también la reversión del orden de desove). Me gusta más esto porque un archivo temporal parece innecesario, pero estoy un poco preocupado sobre si este constructo encadena los procesos de la manera que espero.

  1. es el /dev/stdout que cap está hablando a diferencia de la salida estándar real en el sistema operativo? es decir, con el tubo de entrada - en enc ¿obtendré un canal limpio de datos entre estos dos procesos, incluso si otros procesos están conversando en/dev/stdout en el sistema operativo?
  2. ¿habrá diferencias significativas en el comportamiento con bloqueo/colas? Creo que en mi primer ejemplo la tubería con nombre será una memoria intermedia de 4096 bytes, y se bloqueará en cualquier extremo si cap/enc no están escribiendo/leyendo lo suficientemente rápido, pero corríjanme si estoy equivocado.
  3. ¿Se requiere algún orden especial de desove o terminación, o cualquier otro problema que deba tener en cuenta?

Respuesta

1
  1. /dev/stdout le da la salida estándar para el proceso actual, por lo que debe estar muy bien a usar eso. (en realidad no hay nada 'global' sobre/dev/stdout)
  2. El tamaño de la fifo en el primer ejemplo depende de la configuración de su sistema (no estoy seguro de cómo cambiar eso). Pero el subproceso.Popen le permite definir el tamaño del búfer para sus operaciones de E/S, por lo que debería poder sintonizarlo. Actualización: un poco más de investigación en, he encontrado que hay un límite de 64kB para las tuberías que no se ve afectado por el argumento bufsize. No estoy seguro de cómo evitarlo (excepto para leer con más frecuencia y manejar el almacenamiento en búfer manualmente)
  3. Para su segundo ejemplo, parece que debe comenzar en el orden que dio, ya que necesita que el límite esté disponible antes de comenzar el enc. Alternativamente, puede dejar los dos procesos desconectados y manejar la comunicación entre ellos manualmente.