子进程收到父母的SIGINT [英] Child process receives parent's SIGINT

查看:711
本文介绍了子进程收到父母的SIGINT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用Qt框架一个简易程序。
它使用QProcess中执行RAR和COM preSS一些文件。在我的计划,我赶上SIGINT,做我的code的东西,当它occures:

I have one simple program that's using Qt Framework. It uses QProcess to execute RAR and compress some files. In my program I am catching SIGINT and doing something in my code when it occures:

signal(SIGINT, &unix_handler);

在SIGINT occures,我检查,如果RAR过程完成后,如果没有,我会等待它......问题是,(我认为)RAR过程中也得到的SIGINT这是意味着我的程序,它退出之前它有COM pressed的所有文件。

When SIGINT occures, I check if RAR process is done, and if it isn't I will wait for it ... The problem is that (I think) RAR process also get's SIGINT that was meant for my program and it quits before it has compressed all files.

有没有办法运行RAR过程,这样,当我的程序接收到它,它不会收到SIGINT?

Is there a way to run RAR process so that it doesn't receive SIGINT when my program receives it ?

感谢

推荐答案

如果您正在生成 SIGINT 使用Unix系统上按Ctrl-C,则该信号被发送到整个进程组

If you are generating the SIGINT with Ctrl-c on a Unix system, then the signal is being sent to the entire process group.

您需要使用 setpgid 或的setsid 以把孩子加工成不同的处理组,以便它不会接收由控制终端所产生的信号。

You need to use setpgid or setsid to put the child process into a different process group so that it will not receive the signals generated by the controlling terminal.

请务必仔细阅读 setpgid 页的基本原理部分。这是一个有点棘手,在这里插上所有的潜在的竞争条件。

Be sure to read the RATIONALE section of the setpgid page carefully. It is a little tricky to plug all of the potential race conditions here.

要保证100%没有 SIGINT 将交付给你的孩子的过程,你需要做的是这样的:

To guarantee 100% that no SIGINT will be delivered to your child process, you need to do something like this:

#define CHECK(x) if(!(x)) { perror(#x " failed"); abort(); /* or whatever */ }
/* Block SIGINT. */
sigset_t mask, omask;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
CHECK(sigprocmask(SIG_BLOCK, &mask, &omask) == 0);

/* Spawn child. */
pid_t child_pid = fork();
CHECK(child_pid >= 0);
if (child_pid == 0) {
    /* Child */
    CHECK(setpgid(0, 0) == 0);
    execl(...);
    abort();
}
/* Parent */
if (setpgid(child_pid, child_pid) < 0 && errno != EACCES)
    abort(); /* or whatever */
/* Unblock SIGINT */
CHECK(sigprocmask(SIG_SETMASK, &omask, NULL) == 0);

严格说来,对每一个步骤都需要。你必须阻止情况下,用户在调用命中后按Ctrl-C权的信号。你必须调用 setpgid 在情况下,孩子的 EXECL 发生在父母有时间做任何事情之前。你必须调用 setpgid 中的情况下,父的的运行,并有人打按Ctrl-C中的子之前的有时间做任何事情。

Strictly speaking, every one of these steps is necessary. You have to block the signal in case the user hits Ctrl-C right after the call to fork. You have to call setpgid in the child in case the execl happens before the parent has time to do anything. You have to call setpgid in the parent in case the parent runs and someone hits Ctrl-C before the child has time to do anything.

上面的顺序是笨拙,但它确实处理的竞争条件100%。

The sequence above is clumsy, but it does handle 100% of the race conditions.

这篇关于子进程收到父母的SIGINT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆