Pergunta

Eu estou programando um módulo de comunicação entre processos (Processo A e Processo B).

Existe alguma maneira o segmento de comunicação em B pode ser executado (seja desbloqueio), logo que o processo A termina uma ação específica, quero dizer, sem B fazer qualquer sondagem nem B esperando muito depois de A termina a sua ação?

Quais os conceitos / modelos / padrões de design que regem estas questões? (Algo mais precisa do que a sincronização entre processos). Quais as bibliotecas / métodos que você recomendaria?

Graças.

Edit: eu estou à procura de métodos adequados para cada um dos três sistemas operacionais principais:. MS Windows, Apple Mac OS X, o GNU / Linux

Foi útil?

Solução

Este é o trabalho muito difícil:

Para Unix sistemas operacionais que você pode usar:

  • condição pthread e mutex com o argumento setpshared.

    Nota: ele é suportado bem sob Linux 2.6, Solaris, mas não suportado FreeBSD e Cygwin (não sei sobre o Mac OS X)

  • Para Unixes você também pode usar semáforos nomeados, mas eu não sei o nível de apoio deles

  • Para o Windows, existem alguns eventos ...

Este é o trabalho duro, especialmente para IPC ...

Então, se você quer algo portátil, eu sugiro dar uma olhada em Boost.Interprocess que tem condições e semáforos ...

Mas certifique-se de que todos os recursos suportados em todos os sistemas operacionais que você quer apoio.

Coisas que você deve observar sobre Boost.Interprocess

Verifique cuidadosamente nível de suporte para cada sistema operacional Unix que você precisa para trabalhar, porque usos Boost.Interprosess pthread_ funções * que nem sempre são suportados ... e depois não volta para a emulação - verificar a qualidade de tal emulação

Além disso, verificar como isso funciona no Windows - tanto quanto eu sei que não há "in-shared-memory" mutexes no Win32 API, objetos geralmente nomeadas devem ser utilizados, de modo a verificar o que é suportado e como.

Outras dicas

EDIT: I erroneamente pensou que precisava de sincronização rosca entre, Revista para IPC

Eu acho que você precisa de algo como eventos waitable.

No Windows, você pode usar CreateEvent() , para criar (ou obter um já existente) com o nome do evento auto-reset,.

Quando o processo A concluir o processamento, ele deve chamar SetEvent() , enquanto que o processo B deve chamar WaitForSingleObject() a dormir até a conclusão (ou tempo de espera).

Como alternativa, você pode usar semáforos criados por CreateSemaphore() , inicializado a 0. sinais processar uma conclusão chamando ReleaseSemaphore() , enquanto que processo B usa novamente WaitForSingleObject() para aguardar a conclusão .

Sob Linux e OS X, você pode usar semáforos para um efeito similar. usar sem_open() para criar uma chamada semáforo, com 0 como seu valor inicial.

Quando concluído processo A, ele deve chamar sem_post() para incremento do semáforo, enquanto que o processo B deve chamar sem_wait() a dormir até a conclusão.

NOTA : o método de semáforo pode permitir que várias conclusões a ser sinalizado, você deve lidar com isso definindo uma contagem máxima no Windows, ou verificar o valor atual sem pela sanidade com sem_getvalue()


Eu acho variáveis ??de condição caber o que você está tentando fazer, aqui está uma amostra que iria trabalhar em Linux e 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);
}

No Windows, você pode usar pthreads-win32 , ou variáveis ??de condição nativa sob Vista, consulte página Variáveis ?? MSDN Condição para mais informações.

Referências:

Se os sinais de seus OS suporta você pode desbloquear um mutex de um manipulador de sinal e enviar o sinal do processo A, logo que você terminar a tarefa.

Processo B estaria esperando em um mutex ou outra ferramenta de sincronização e A estaria trabalhando em qualquer outra coisa, então quando acabamentos envia sinal USR1 por exemplo, e manipulador USR1 no processo B abre a ferramenta de sincronização correspondente.

O mais comum é usar select () / poll (). Ambos podem verificar vários descritores de arquivos se há entrada disponível. Ambos recebem um parâmetro de tempo limite - isso vai impedir espera ocupado, que pode consumir 100% da CPU. Esta solução é muito adequado para aplicações / médios pequenos.

Outra abordagem é fazer polling em segmento separado.

Se você estiver indo para desenvolver um aplicativo grande pena da olhar para ACE quadro ou impulso . Estes quadros são soluções multi-plataforma, bem concebido e bem testado.

Bem, na minha opinião e experiência, a melhor maneira de fazer isso de uma maneira portátil e simples é usar soquetes. Além disso, você tem a possibilidade de ter os dois processos na máquina diferente (se necessário). Além disso, você pode Extand a comunicação para lidar com mais de Sincronização.

Se você não quiser pesquisa, use um segmento que espera por uma mensagem sincronizada em um soquete. Você lê a tomada de uma forma de bloqueio. Quando você receber a mensagem de você usar uma sincronização multithread padrão para lidar com a sua sincronização. No seu caso, como B deve esperar até que encerra uma, você só tem que ler de forma a bloquear em seu processo.

Para ser uso portátil uma biblioteca tomada portátil como impulso ou ptypes ou o que quer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top