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

发布于 2024-11-27 07:19:58 字数 1168 浏览 0 评论 0原文

#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 秒?有什么办法可以实现这个目标吗?

#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. 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. Why doesn't the parent process resume to "exact location" before handling signal, which is sleeping 20 more seconds? Is there a way that I can achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

平定天下 2024-12-04 07:19:58

如果出现信号,sleep(3) 不会重新启动。

返回值:如果请求的时间已过,则返回零,或者返回的数量
如果通话被信号打断,还剩几秒要睡觉
处理程序。

所以你应该检查返回值并再次睡眠。像(未经测试)的东西:

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

sleep(3) isn't restarted in the event of a signal.

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)))
    ;
浴红衣 2024-12-04 07:19:58

考虑一下您可能想要中断阻塞操作/select()/poll()/sleep()。一种方法是发送一个信号,这可能会导致当前函数以 EINTR 退出。

有一个 SA_RESTART 标志会导致某些函数在收到信号后重新启动,主要是 read()write()。其他函数的行为取决于实现。

Consider that you may want to interrupt a blocking operation/select()/poll()/sleep(). One way to do it is to send a signal, which may cause the current function to exit with EINTR.

There is a SA_RESTART flag that causes some functions to be restarted on receipt of a signal, mainly read() and write(). Other functions' behaviour depends on implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文