2009-04-03 8 views
8

Tengo dos procesos separados: un programa C que genera valores separados por comas seguidos de una línea nueva cada segundo, y un programa Perl que acepta datos (en el mismo formato) y procesa estos datos.¿Cómo permito que se comuniquen dos procesos simultáneos?

Los productos de los programas C (a través de printf) Valores como tal:

1, 2, 3, 4, 5, 6 
7, 8, 9, 10, 11, 12 
... 

El programa Perl se sienta en un bucle infinito esperando en una base de línea para STDIN con el fin de procesar estos datos:

while ($line = <STDIN>) 
{ 
    chomp($line) # Line should now read "1,2,3,4,5,6" 
    # Process data 
} 

Quiero que estos dos procesos se comuniquen en tiempo real. Los tubos bash estándar no funcionan (por ejemplo, process1 | process2) porque el programa Perl espera a que el primer programa termine antes de procesar la entrada.

¿Alguien tiene alguna idea, sugerencia o idea sobre una solución a este problema? ¡Gracias de antemano!

+0

hablando en sentido estricto, esto no tiene nada que ver con "tiempo real" – andersoj

+0

Tiene toda la razón, escribí esto rápidamente y no se me ocurrió una mejor manera de explicar cómo quería que estos procesos funcionaran. Concurrente puede haber sido una mejor opción. –

+0

Concurrente es mucho mejor, y hay un botón de edición para que lo solucione. – derobert

Respuesta

16

Las tuberías deberían estar bien para esto; solo necesita controlar cuándo se vacía el resultado de su programa C para que esté disponible para el script de Perl de forma incremental. Puede hacer esto en el programa C usando fflush(), lo que forzará que el buffer de su programa C se despliegue para que el programa perl pueda leerlo.

No hay nada inherente en las tuberías que haga que el programa perl espere a que el programa C termine de escribir antes de procesar su salida. Su programa Perl está escrito para que se procesa STDIN una línea a la vez:

while ($line = <STDIN>) { ... } 

<> en este contexto se lee una línea de STDIN, pero si no hay uno disponible, se bloqueará hasta que uno es. Una llamada al fflush() del programa C hará que esto suceda.

Eche un vistazo a Wikipedia article on Pipelines. La sección de implementación brinda una breve descripción de cómo se almacenan las tuberías en búfer, lo que debería ayudarlo a comprender cómo se comunican sus procesos. Las tuberías do permiten la concurrencia entre los procesos, y los procesos de lectura y escritura en las tuberías son administrados por el planificador al igual que otros procesos. Tu problema aquí es con el almacenamiento en búfer.

+0

Pensé que los programas C descargaban todos los resultados cada vez que imprimían una nueva línea. –

+0

Has acertado con esta respuesta: incluso he explorado fflush pero nunca pensé usarlo en stdout.Y debido a la naturaleza del comportamiento del programa Perl, lo había confundido con 'esperar' en el programa c. ¡Agregue fflush (stdout) después de mis declaraciones de printf y funcionó sin problemas! ¡¡Gracias!! –

+0

@Chris Lutz, la descarga automática solo ocurre si la transmisión está en modo de línea en búfer, lo que generalmente solo es cierto si la transmisión está abierta en un tty. Una vez que stdout es una tubería, su valor predeterminado es un buffer completo para un mejor rendimiento. – RBerteig

5

El programa C debe fflush() sus búfers de salida explícitamente, o usar un pty. Este último es mucho más incómodo pero mantiene el código C más simple. Pruebe con "man 3 fflush" si esto no le es familiar.

+0

Usar un pty es exagerado; enjuagar la salida es importante si usa stdio en el código C (y no material si usa write() directamente). –

+0

Una pty solo es necesaria si los dos procesos deben interactuar, y en realidad solo si uno o ambos deben ignorar el hecho de tener un no humano como parte interactiva. Los Ptys tampoco son muy portátiles fuera de las plataformas tipo Unix. – RBerteig

+0

Estoy de acuerdo en que pty es excesivo, pero engaña al programa C para autoflush después de cada nueva línea. En ese sentido (¡y solo en ese sentido!) Hace que el programa C sea más simple a expensas de un entorno más complicado. –

Cuestiones relacionadas