2011-03-16 20 views
6

No tengo mucha experiencia con multihilo y estoy escribiendo un programa c que creo que es adecuado para ejecutarse en dos subprocesos. El programa escuchará en el puerto en serie los datos, leerá y procesará los nuevos datos cuando estén disponibles, y publicará los datos procesados ​​más recientes en otros módulos (irrelevantes) a través de un tercero IPC api (se llama confusamente IPC) cuando se solicite.Ayuda de diseño de programa multiproceso c

Para recibir la solicitud de publicar datos a través de IPC, el programa debe llamar a IPC_listenwait (wait_time) ;. Luego, si se recibe una solicitud de publicación mientras se escucha "listeningwaiting", se invoca un controlador para publicar los datos más nuevos.

Una opción es hacer esto en un hilo como:

for(;;) { 
    read_serial(inputBuffer); 
    process_data(inputBuffer, processedData); //Process and store 
    IPC_listenwait(wait_time); //If a request to publish is received during this, 
}       //then a handler will be invoked and the newest piece of   
          //processedData will be published to other modules 

publishRequestHandler() { //Invoked when a message is received during IPC_listenwait 
    IPC_publish(newest(processedData)); 
} 

Y esto funciona, pero para la aplicación es importante que el programa es muy sensible a la solicitud de publicación de nuevos datos, y que el los datos publicados son los más nuevos disponibles. Estos objetivos no están satisfechos con lo anterior porque los datos pueden llegar después de que el proceso comience a escucharse y antes de que se reciba un mensaje de solicitud de publicación. O el proceso puede estar leyendo/procesando cuando un mensaje de solicitud de publicación es entrante, pero no podrá atenderlo hasta la próxima llamada IPC_listenwait.

El diseño único que puedo pensar es tener un hilo para leer, lo que acaba de hacer algo como:

readThread() { 
    for(;;) { //pseudocode 
     select(); 
     read(inputBuffer); 
     process(inputBuffer, processedData); 
    } 
} 

Y tienen el hilo principal sólo escuchar los mensajes entrantes:

mainThread() { 
    IPC_listenwait(forever); 
} 

publishRequestHandler() { //Invoked when a message is received during IPC_listenwait 
    IPC_publish(newest(processedData)); 
} 

¿Es este el diseño que usarías? De ser así, ¿tendré que usar un semáforo cuando acceda o escriba processedData?

¿Esto me dará una buena receptividad?

Gracias

Respuesta

4

Estás por el buen camino.

Lo único que hay que tener en cuenta es el acceso concurrente a los datos publicables, porque no quieres que un hilo lo ataque mientras otro intenta leerlo. Para evitar eso, use un par de búferes y un puntero protegido por mutex para cualquiera que se considere actual. Cuando process_data() tiene algo listo, debe volcar sus resultados en el búfer no actual, bloquear el mutex del puntero, volver a marcar el puntero al búfer que contiene los datos nuevos y luego liberar el mutex. Del mismo modo, el editor debe bloquear el mutex del puntero mientras lee los datos actuales, lo que obligará a esperar a todo lo que quiera bloquearlo. Esto es un poco más complejo que tener un único buffer protegido por mutex, pero asegurará que siempre tenga algo actual para publicar mientras se preparan nuevos datos.

Si su proceso de procesamiento lleva suficiente tiempo para poder leer múltiples conjuntos de datos, puede dividir el hilo de lectura/proceso en dos y dejar que el lector se asegure de que el procesador sea el último y el mejor para donar. No acabarás procesando cosas que nunca publicarás.

Excelente primera pregunta, por cierto. Tener un voto favorable.

+0

¡Ahh, la solución de dos amortiguadores es simple pero genio! Gracias –

Cuestiones relacionadas