Pregunta

Estoy programando un módulo de comunicación entre procesos (Proceso A y Proceso B).

¿Hay alguna forma de que el hilo de comunicación en B pueda ejecutarse (desbloquearse) tan pronto como el proceso A finalice una acción específica, es decir, sin B haciendo ninguna encuesta ni B esperando demasiado después de que A finalice su acción?

¿Cuáles son los conceptos / modelos / patrones de diseño que rigen estos temas? (Algo más preciso que la sincronización entre procesos). ¿Qué bibliotecas / métodos me recomiendan?

Gracias.

Editar: Estoy buscando métodos adecuados para cada uno de los tres sistemas operativos principales: MS Windows, Apple Mac OS X, GNU / Linux.

¿Fue útil?

Solución

Este es un trabajo bastante difícil:

Para sistemas operativos Unix puede usar:

  • condición pthread y mutex con argumento setpshared.

    Nota: es compatible con Linux 2.6, Solaris, pero no es compatible con FreeBSD y Cygwin (no sabe acerca de Mac OS X)

  • Para Unixes también puede usar semáforos con nombre, pero no sé el nivel de soporte de ellos

  • Para Windows hay algunos eventos ...

Este es un trabajo duro, especialmente para IPC ...

Entonces, si quieres algo portátil, te sugiero que eches un vistazo a Boost.Interprocess que tiene condiciones y mutexes ...

Pero asegúrese de que todas las funciones sean compatibles con todos los sistemas operativos que desee admitir.

Cosas que debe tener en cuenta sobre Boost.Interprocess

Verifique cuidadosamente el nivel de soporte para cada sistema operativo Unix con el que necesita trabajar, porque Boost.Interprosess utiliza funciones pthread_ * que no siempre son compatibles ... y luego vuelve a la emulación; verifique la calidad de dicha emulación

Además, compruebe cómo funciona esto en Windows, por lo que sé, no hay "in-shared-memory". mutexes en Win32 API, generalmente se deben usar objetos con nombre, así que verifique qué es compatible y cómo.

Otros consejos

EDITAR: erróneamente pensé que necesitabas sincronización entre hilos, Revisado para IPC

Creo que necesitas algo como eventos esperables.

En Windows puede usar CreateEvent ( ) , para crear (u obtener un evento) con nombre y reinicio automático.

Cuando el proceso A completa el procesamiento, debe llamar a < code> SetEvent () , mientras que el proceso B debe llamar a WaitForSingleObject () para dormir hasta la finalización (o tiempo de espera).

Alternativamente, puede usar semáforos creados por CreateSemaphore () , inicializado a 0. El proceso A señala la finalización llamando a ReleaseSemaphore () , mientras que el proceso B nuevamente utiliza WaitForSingleObject () para esperar la finalización.

En Linux y OS X puede usar semáforos con un efecto similar. use sem_open () para crear un semáforo con nombre, con 0 como valor inicial.

Cuando se completa el proceso A, debe llamar a sem_post () para incrementar el semáforo, mientras que el proceso B debe llamar a sem_wait () para dormir hasta su finalización.

NOTA : el método de semáforo puede permitir la señalización de múltiples finalizaciones, debe manejar esto configurando un conteo máximo en Windows o comprobando el valor sem actual para la cordura con sem_getvalue ()


Creo que las variables de condición se ajustan a lo que está intentando hacer, aquí hay una muestra que funcionaría en Linux y OSX

#include <pthread.h>
/* no error checking, quick and dirty sample */
pthread_mutex_t g_mutex;
pthread_cond_t g_cond;
int a_done = 0;

void init(void)
{
    pthread_mutex_init(&g_mutex, NULL);
    pthread_cond_init(&g_cond, NULL);
}

void thread_a(void *arg)
{
    /* do something here... */
    pthread_mutex_lock(&g_mutex);
    a_done = 1;
    pthread_cond_signal(&g_cond);
    pthread_mutex_unlock(&g_mutex);
}

void thread_b(void *arg)
{
    /* wait for a to complete */
    pthread_mutex_lock(&g_mutex);
    while (!a_done)
        pthread_cond_wait(&g_cond, &g_mutex);
    a_done = 0;
    pthread_mutex_unlock(&g_mutex);
}

En Windows, puede usar pthreads-win32 , o variables de condición nativas en Vista, consulte la página de variables de condición de MSDN para obtener más información.

Referencias:

Si su sistema operativo admite señales, puede desbloquear un mutex desde un controlador de señales y enviar la señal desde el proceso A tan pronto como termine la tarea.

El proceso B estaría esperando un mutex u otra herramienta de sincronización y A estaría trabajando en lo que sea, luego, cuando finalice, se envía la señal USR1, por ejemplo, y el controlador USR1 en el proceso B desbloquea la herramienta de sincronización correspondiente.

Lo más común es usar select () / poll (). Ambos pueden verificar varios descriptores de archivos si hay entradas disponibles. Ambos reciben un parámetro de tiempo de espera: esto evitará una espera ocupada, que puede consumir 100% de CPU. Esta es una solución muy adecuada para aplicaciones pequeñas / medianas.

Otro enfoque es hacer el sondeo en un hilo separado.

Si va a desarrollar una gran aplicación, vale la pena mirar hacia ACE marco o boost . Estos marcos son soluciones multiplataforma, bien diseñadas y probadas.

Bueno, en mi opinión y experiencia, la mejor manera de hacerlo de una manera portátil y simple es usar enchufes. Además, tiene la posibilidad de tener los dos procesos en una máquina diferente (si es necesario). Además, puede ampliar la comunicación para manejar más que la sincronización.

Si no desea sondear, use un hilo que espere un mensaje sincronizado en un socket. Usted lee el zócalo en forma de bloqueo. Cuando recibe el mensaje, usa una sincronización estándar de subprocesos múltiples para manejar su sincronización. En su caso, ya que B debería esperar hasta que A termine, solo tiene que leer de manera bloqueadora en su proceso.

Para ser portátil, use una biblioteca de socket portátil como boost o ptypes o lo que sea.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top