使用alarm()实现进程超时

Using alarm() to implement process timeout

我正在尝试建立一种机制,该机制将等待 child 进程一段指定的时间并相应地执行其他操作。

我试过以下方法:

#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <iostream>

volatile sig_atomic_t p_flag = false;

pid_t makeproc ()
{
  pid_t pid;

  pid = fork();

  // parent
  if (pid) return pid;

  //child 
  std::cout << "Child created\n";
  sleep(5);
  exit(0);
}

void sig_handle (int sig)
{
  std::cout << "Handler called\n"; 
  p_flag = true;
}

int main() {
  int status;
  pid_t child;
  int ret;

  signal (SIGALRM, sig_handle);
  alarm(2);

  child = makeproc();
  pid_t p = waitpid(-1, &status, 0);
  std::cout << "PID: " << p << " FLAG: " << p_flag;

  return 0;
}

我从中得到的是,waitpid() 没有被 SIGALRM 中断,并且 parent 继续等待直到进程完成。输出显示生成了 SIGALRM 并调用了处理程序。

Child created
Handler called
PID: 31683 FLAG: 1

我无法在处理程序中执行 kill() 来终止 child。当 SIGALRM 被引发时,我怎样才能将 wait() 变为 return?

很可能,在您的 OS 版本中,signal 调用安装处理程序并设置了 SA_RESTART 标志。设置此标志后,系统调用会在信号处理程序后自动重新启动。

要控制它,不要使用过时和弃用的 signal,而是使用 sigaction,并确保不指定 SA_RESTART 标志。这应该可以解决您的问题。