2012-03-02 7 views
0

私は父と子供を同期しようとしていますが、次のコードは動作しません(明らかにusr_interrupt ++はアトミックではありません)。セマフォーはどちらも助けてくれないようです。sigsuspend()によるデッドロック

#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <cstdlib> 
#include <iostream> 
#include <unistd.h> 
#include <cstring> 
#include <string> 
#include <semaphore.h> 
#include <fcntl.h> 

using namespace std; 

/* When a SIGUSR1 signal arrives, set this variable. */ 
volatile sig_atomic_t usr_interrupt; 
sem_t *mutex; 
char* SEM_NAME; 

void 
synch_signal (int sig) 
{ 
    // sem_wait(mutex); 
    usr_interrupt++; 
    // sem_post(mutex); 
} 

/* The child process executes this function. */ 
void 
child_function (void) 
{ 

    /* Perform initialization. */ 
    cerr << "I'm here!!! My pid is " << (int)getpid() << " my usr_int=" << usr_interrupt << endl; 
    /* Let parent know you're done. */ 
    kill (getppid(), SIGUSR1); 
    /* Continue with execution. */ 
    cerr << "Bye, now...." << endl; 
    exit(0); 
} 

int 
main (void) 
{ 
    usr_interrupt = 0; 

    string s_sem_name = "lir"; 
    SEM_NAME = new char[s_sem_name.size()+1]; 
    memcpy(SEM_NAME, s_sem_name.c_str(), s_sem_name.size()); 
    SEM_NAME[s_sem_name.size()] = '\0'; 
    mutex = sem_open (SEM_NAME,O_CREAT,0644,1); 
    if(mutex == SEM_FAILED) { 
    perror("unable to create semaphore"); 
    sem_unlink(SEM_NAME); 
    exit(-1); 
    } 


    struct sigaction usr_action; 
    sigset_t mask, oldmask; 
    pid_t child_id, child_id2; 

    /* Set up the mask of signals to temporarily block. */ 
    sigemptyset (&mask); 
    sigaddset (&mask, SIGUSR1); 

    /* Establish the signal handler.*/ 
    usr_action.sa_handler = synch_signal; 
    usr_action.sa_flags = 0; 
    sigaction (SIGUSR1, &usr_action, NULL); 

    /* Create the 2 children processes. */ 
    child_id = fork(); 
    if (child_id == 0) 
    child_function(); 

    child_id2 = fork(); 
    if (child_id2 == 0) 
    child_function(); 

    /* Wait for a signal to arrive. */ 
    sigprocmask (SIG_BLOCK, &mask, &oldmask); 
    while (usr_interrupt != 2) { 
    sigsuspend (&oldmask); 
    } 
    sigprocmask (SIG_UNBLOCK, &mask, NULL); 


    /* Now continue execution. */ 
    puts ("That's all, folks!"); 

    return 0; 
} 

誰でも修正を提案できますか? (私は、スレッドを使用することはできません) 、ベスト - 同じ種類のLiron

+0

AutoLocksを使用してコードを書き換えます。 – AlexTheo

答えて

1

You can't count signals. 2つの信号は、その型の一つの信号と同じ意味論的な意味を持ちます。 USR1とUSR2のような2つの異なる信号タイプを使用できます。しかし正直なところ、コミュニケーションの仕組みとしてシグナルを使うべきではありません。パイプのような賢明なものを使用してください。

+0

Davidに感謝します。しかし、子供が別のプロセスにいる場合はどうなりますか? (例:I forkとexec)?また、私は通信のためのプロセスのための共有メモリを持っているので、私は同期するものが欲しいだけです。 –

+0

セマフォを使用します。または、名前付きパイプを使用します。またはソケット。 –

関連する問題