信号处理和 fork() 之间的竞争条件

问题描述 投票:0回答:2

我想为

SIGHUP
安装一个信号处理程序,以便传播给另一个进程组中的孩子,但似乎在 POSIX 中我只能从
fork()
的返回中获取孩子的 PID。

那么,有没有办法避免当您在

fork()
返回父级之前收到 SIGHUP 而在
setpgid()
已经在子级中执行之后发生的竞争条件?

c process posix
2个回答
6
投票

似乎在POSIX中我只能从

fork()
的返回中获取孩子的PID。

当然你不能得到孩子的PIDs before

fork()
返回,因为孩子在那之前不存在于父母的时间轴中。
fork()
的返回值确实是父级获得 PID 的 POSIX 祝福方式,是的。

那么,有没有办法避免当您在

fork()
返回父级之前收到 SIGHUP 而在
setpgid()
已经在子级中执行之后发生的竞争条件?

是的。在分叉之前让父块

SIGHUP
(见
sigprocmask()
)。父母和/或孩子(继承了父母的信号处置)应该在准备好时解锁
SIGHUP


0
投票

与其直接在信号处理程序中转发信号,不如设置一个标志来防止主代码执行

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可以在循环之后进行。

© www.soinside.com 2019 - 2024. All rights reserved.