我想为
SIGHUP
安装一个信号处理程序,以便传播给另一个进程组中的孩子,但似乎在 POSIX 中我只能从 fork()
的返回中获取孩子的 PID。
那么,有没有办法避免当您在
fork()
返回父级之前收到 SIGHUP 而在 setpgid()
已经在子级中执行之后发生的竞争条件?
似乎在POSIX中我只能从
的返回中获取孩子的PID。fork()
当然你不能得到孩子的PIDs before
fork()
返回,因为孩子在那之前不存在于父母的时间轴中。 fork()
的返回值确实是父级获得 PID 的 POSIX 祝福方式,是的。
那么,有没有办法避免当您在
返回父级之前收到 SIGHUP 而在fork()
已经在子级中执行之后发生的竞争条件?setpgid()
是的。在分叉之前让父块
SIGHUP
(见sigprocmask()
)。父母和/或孩子(继承了父母的信号处置)应该在准备好时解锁SIGHUP
。
与其直接在信号处理程序中转发信号,不如设置一个标志来防止主代码执行
fork
ing,并使其在处理完待处理的返回值后将信号发送到合适位置的子级 fork
.
伪代码示例(无效的 C):
volatile sig_atomic_t sighup_occurred = 0;
void sighup_handler(int sig) {
sighup_occurred = 1;
}
int main(void) {
sigaction(SIGHUP, ...);
while(some_condition){
if(!sighup_occurred) {
pid = fork();
/* distinction between parent and child needed here */
pids[child_count++] = pid;
}
if(sighup_occurred) {
for(int i = 0; i < child_count; i++) {
kill(pids[i], SIGHUP);
}
terminate_program();
} else {
do_normal_work();
}
}
}
根据程序的不同,标志
sighup_occurred
也可以用于退出主循环,而孩子们的kill
ing可以在循环之后进行。