2012-03-02 149 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 2012-03-02 16:31:11

回答

1

You can't count signals.兩個信號具有相同的語義含義該類型的一個信號。您可以使用兩種不同的信號類型,如USR1和USR2。但說實話,你不應該使用信號作爲溝通機制。使用像管子這樣明智的東西。

+0

謝謝大衛。但如果孩子處於不同的過程呢? (例如我叉和執行)?另外,我爲通信過程共享內存,所以我只想要一些同步。 – 2012-03-02 15:06:25

+0

然後使用信號量。或者使用命名管道。或套接字。 – 2012-03-02 15:12:38