首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >子进程是否也应该解锁被阻塞的SIGCHLD信号?

子进程是否也应该解锁被阻塞的SIGCHLD信号?
EN

Stack Overflow用户
提问于 2019-04-25 04:36:37
回答 1查看 926关注 0票数 2

我正在尝试理解阻塞和解锁信号是如何工作的,并且我正在尝试理解下面这段代码。具体地说,我看的是第28行(代码中的注释):int a = sigprocmask(SIG_UNBLOCK, &mask, NULL);,也就是信号在子对象中被解锁的地方。

我得到代码的教科书说,代码使用信号阻塞,以确保程序在执行删除功能(简化为printf("deleting %d\n", pid);)之前执行其添加功能(简化为printf("adding %d\n", pid);)。这对我来说很有意义;通过阻塞SIGCHLD信号,然后在执行add函数后解除阻塞,我们确保在执行add函数之前不会调用处理程序。然而,我们为什么要解锁孩子身上的信号呢?这难道不是通过立即解除阻塞来消除整个阻塞的点,允许孩子在父节点添加之前删除它吗?

然而,无论我是否注释掉了该行,输出(在代码之后描述)都是相同的,这意味着这显然不是所发生的事情。教科书上写道:

“请注意,子级继承了父级的阻塞集,因此在调用execve之前,我们必须小心解锁子级中的SIGCHLD信号。”

但在我看来,解锁仍然会导致处理程序被调用。这一行到底是做什么的?

void handler(int sig) {
    pid_t pid;
    printf("here\n");
    while ((pid = waitpid(-1, NULL, 0)) > 0); /* Reap a zombie child */
    printf("deleting %d\n", pid); /* Delete the child from the job list */
}

int main(int argc, char **argv) {
    int pid;
    sigset_t mask;
    signal(SIGCHLD, handler);
    sigemptyset(&mask);
    sigaddset(&mask, SIGCHLD);
    sigprocmask(SIG_BLOCK, &mask, NULL); /* Block SIGCHLD */

    pid = fork();
    if (pid == 0) {
        printf("in child\n");

        int a = sigprocmask(SIG_UNBLOCK, &mask, NULL); // LINE 28

        printf("a is %d\n",a);
        execve("/bin/date", argv, NULL);
        exit(0);
    }

    printf("adding %d\n", pid);/* Add the child to the job list */
    sleep(5);
    printf("awake\n");

    int b = sigprocmask(SIG_UNBLOCK, &mask, NULL);
    printf("b is %d\n", b);
    sleep(3);

    exit(0);
}

输出:

adding 652

in child

a is 0

Wed Apr 24 20:18:04 UTC 2019

awake

here

deleting -1

b is 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55838182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档