与sigsuspend()的死锁

时间:2012-03-02 13:37:37

标签: c++ linux process signals deadlock

我正在尝试同步父亲和孩子,以下代码不起作用(显然usr_interrupt ++不是原子的)。信号量似乎也没有帮助。

#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

1 个答案:

答案 0 :(得分:1)

You can't count signals.两个相同类型的信号与该类型的一个信号具有相同的语义含义。您可以使用两种不同的信号类型,如USR1和USR2。但老实说,你不应该使用信号作为沟通机制。使用像管道一样合理的东西。