简体   繁体   中英

Child doesn't continue running after receiving signal using pause()

  ...

  signal( SIGUSR1, sigusr);
  bla = 0;
  for(;;)
  {
    if(pid=fork()==0)
    {
      fprintf(stderr,"Child %d: Waiting in queue.\n",getpid());
      pause();
      fprintf(stderr,"im here"); //can't get to this line
      kill(deque(q),SIGUSR1)
      _exit(0);
    }
    else
    {
      sem_wait(&q2);
      enque(q,pid);
      sem_post(&q2);
      if(!bla)
      {
        bla=1;
        sem_wait(&q2);
        kill(deque(q),SIGUSR1);
        sem_post(&q2);
      }
      sleep(n);
    }
  }

  ...

void sigusr()
{
  signal(SIGUSR1, sigusr);
  fprintf(stderr, "Child %d: Got it.\n", getpid());
}

The expression pid=fork()==0 does not work as you expect it to. It assigns the valie of fork() == 0 to the variable pid , because of the operator precedence for equality is higher than for assignment.

That means that pid will be either 0 or 1 , neither a correct process identifier.

Change to (pid = fork()) == 0 instead.

In addition to pid=fork()==0 there is a race condition, the child may receive the signal before the call to pause() , and then wait for another signal in pause() .

To avoid this problem:

  1. Block the signal using sigprocmask .
  2. Check if is appropriate to wait.
  3. Wait for the signal using sigsuspend .
  4. Unblock the signal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM