我有一个使用Qt Framework的简单程序.它使用QProcess来执行RAR并压缩一些文件.在我的程序中,我正在捕获SIGINT并在代码中执行某些操作:
signal(SIGINT, &unix_handler);
Run Code Online (Sandbox Code Playgroud)
当SIGINT发生时,我检查RAR进程是否完成,如果不是,我将等待它...问题是(我认为)RAR进程也得到了SIGINT,这是我的程序,它退出之前它压缩了所有文件.
有没有办法运行RAR进程,以便在我的程序收到它时它不会收到SIGINT?
谢谢
Nem*_*emo 28
如果要SIGINT在Unix系统上使用Ctrl-c 生成,则信号将发送到整个进程组.
您需要使用setpgid或setsid将子进程放入不同的进程组,以便它不会接收控制终端生成的信号.
[编辑]
请务必setpgid仔细阅读页面的RATIONALE部分.在这里插入所有潜在的竞争条件有点棘手.
为了保证100%SIGINT将不会交付给您的子进程,您需要执行以下操作:
#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);
Run Code Online (Sandbox Code Playgroud)
严格来说,这些步骤中的每一步都是必要的.如果用户在调用后立即按Ctrl-C,则必须阻止信号fork.如果父母有时间做任何事情,你必须打电话setpgid给孩子execl.如果父项运行并且某人在孩子有时间做任何事情之前按某人Ctrl-C,你必须setpgid在父母中调用.
上面的顺序是笨拙的,但它确实处理了100%的竞争条件.