简体   繁体   English

为什么父进程在处理信号后没有返回到确切的位置?

[英]Why doesn't parent process return to the exact location after handling signal?

#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;
}

The result that I got is after 10 seconds, both child and parent process prints out its message then exit. 我得到的结果是10秒钟后,子进程和父进程都会打印出其消息,然后退出。 What I expect is child process prints out the message first, then parent process will sleep about 20 more seconds before printing out its message and exit. 我期望的是子进程首先打印出消息,然后父进程将在打印消息并退出之前再休眠约20秒钟。 Why doesn't the parent process resume to "exact location" before handling signal, which is sleeping 20 more seconds? 为什么父进程在处理20秒钟以上的睡眠信号之前不恢复到“精确位置”? Is there a way that I can achieve this? 有没有办法可以做到这一点?

sleep(3) isn't restarted in the event of a signal. sleep(3)不会重新启动。

Return Value: Zero if the requested time has elapsed, or the number of seconds left to sleep, if the call was interrupted by a signal handler . 返回值:如果请求的时间已经过去,则返回零; 如果调用被信号处理程序中断返回睡眠状态的秒数。

So you should check the return value and sleep again. 因此,您应该检查返回值并再次休眠。 Something like (untested): 像(未经测试的):

rc = 30;
while ((rc = sleep(rc)))
    ;

Consider that you may want to interrupt a blocking operation/ select() / poll() / sleep() . 考虑到您可能想中断阻塞操作/ select() / poll() / sleep() One way to do it is to send a signal, which may cause the current function to exit with EINTR . 一种方法是发送信号,这可能导致当前函数通过EINTR退出。

There is a SA_RESTART flag that causes some functions to be restarted on receipt of a signal, mainly read() and write() . 有一个SA_RESTART标志,该标志使某些函数在接收到信号后重新启动,主要是read()write() Other functions' behaviour depends on implementation. 其他功能的行为取决于实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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