繁体   English   中英

C ++流程分叉和sigalarm

[英]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.

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