Почему родительский процесс не возвращается в точное местоположение после обработки сигнала? - PullRequest
2 голосов
/ 30 июля 2011
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>

sig_atomic_t child_exit_status;

void clean_up_child_process (int signal_number)
{
  /* Clean up the child process.  */
  int status;
  wait (&status);
  /* Store its exit status in a global variable.  */
  child_exit_status = status;
}

int main ()
{
  /* Handle SIGCHLD by calling clean_up_child_process.  */
  struct sigaction sigchld_action;
  memset (&sigchld_action, 0, sizeof (sigchld_action));
  sigchld_action.sa_handler = &clean_up_child_process;
  sigaction (SIGCHLD, &sigchld_action, NULL);

  /* Now do things, including forking a child process.  */
  /* ...  */
  pid_t t = fork();
  if (t!=0) {
      // parent
      sleep(30);    // After handling signal, why does it not continue to sleep 20 (30-10) more seconds?
      printf("Parent exits\n");
  }
  else {
      // child
      sleep(10);
      printf("child exists\n");
  }

  return 0;
}

Результат, который я получил через 10 секунд, и дочерний, и родительский процессы выводят свое сообщение, а затем завершаются.Я ожидаю, что дочерний процесс сначала распечатает сообщение, затем родительский процесс будет спать еще около 20 секунд, прежде чем распечатать свое сообщение и выйти.Почему родительский процесс не возвращается в «точное местоположение» перед обработкой сигнала, который спит еще 20 секунд?Есть ли способ, которым я могу достичь этого?

Ответы [ 2 ]

5 голосов
/ 30 июля 2011

sleep(3) не перезапускается в случае сигнала.

Возвращаемое значение: ноль, если запрошенное время истекло, или число секунд до сна , если вызов был прерван сигналом обработчик .

Так что вы должны проверить возвращаемое значение и снова заснуть. Что-то вроде (не проверено):

rc = 30;
while ((rc = sleep(rc)))
    ;
0 голосов
/ 30 июля 2011

Учтите, что вы можете прервать операцию блокировки / select() / poll() / sleep().Один из способов сделать это - отправить сигнал, что может привести к выходу текущей функции с помощью EINTR.

. Имеется флаг SA_RESTART, который вызывает перезапуск некоторых функций при получении сигнала,в основном read() и write().Поведение других функций зависит от реализации.

...