[英]C++ Process fork and sigalarm
该程序的目标是分叉并使孩子进入睡眠状态,而父级循环无限地等待中断。 当我按下^ C时,它将调用void parent
函数。 但是,此部分有效,来自kill ( pid, SIGALRM )
的消息不起作用。 我检查了pid
是该孩子的正确进程ID。
我搜索了一段时间,但没有发现我在做什么错。 在从子进程到父进程之前kill ( pid, SIGALRM )
我使用了kill ( pid, SIGALRM )
,但我不知道为什么这不起作用。
#include <signal.h>
#include <unistd.h>
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
int pid;
void parent ( int sig )
{
kill ( pid, SIGALRM );
cout << "I'm a parent " << getpid() << " My child is " << pid << endl;
}
void child ( int sig )
{
cout << "I am " << getpid() << "my parent is " << getppid()<< endl;
cout << "Use ctrl+backslash to actually end the program" << endl;
}
int main()
{
pid = fork();
if(pid == 0)
{ //Child process
cout << "Child pid = " << getpid() << " Waiting for interrupt." << endl;
(void) signal ( SIGALRM, child );
pause();
}
else if(pid > 0)
{ //Parent
sleep(2);
cout << "child pid = " << pid << endl;
struct sigaction act;
act.sa_handler = parent;
sigemptyset ( &act.sa_mask);
sigaction (SIGINT, &act, 0);
while(1)
{
sleep ( 1 );
}
}
return 0;
}
好的,所以我找出了问题所在。
当我按^ C时,它将捕获主进程中的中断,但杀死子进程。 当我从程序内部运行system("ps")
,它表明子a.out进程已失效。 为了解决这个问题,我在孩子的过程中添加了以下内容:
struct sigaction act;
act.sa_handler = CHILD_PRESERVER;
sigemptyset ( &act.sa_mask);
sigaction (SIGINT, &act, 0);
CHILD PRESERVER
是一个伪函数,除了保持活动状态外什么也没做。
它没有看到此解决方案非常优雅,因此,如果有人有更正确的方法,请发布它。
您可以只使用signal(SIGINT, SIG_IGN);
来完成与sigaction
解决方案相同的操作signal(SIGINT, SIG_IGN);
最初使您绊倒的事情(并且经常使处理ctrl-C和信号的新程序员绊倒)的是ctrl-C向整个过程组发送信号,而不是向单个过程发送信号-该组中的每个过程都会得到信号。 信号发送到的进程组是终端的前台进程组。
因此,这为您提供了许多处理/控制ctrl-C中断的方法。 您可以让每个进程都安装自己的SIGINT处理程序(完成后)。 或者,您可以仔细管理您的流程组,将子级放入他们自己的流程组(通常不会成为前台流程组),这样他们就不会首先收到信号。
您可以使用setpgrp(2)/ setpgid(2)系统调用来管理进程组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.