c - 父进程正在向子进程发出信号,但子进程的信号处理需要改进

标签 c linux signals fork signal-handling

我正在做一些考试练习题,其中一个问题给出了两段代码,分别称为 Parent.c 和 child.c 。父级创建一个子级并向其发射信号,子级每次收到信号时都会显示一条消息。 child 将用剩下的时间打印来自 main 的消息。问题是描述 child.c 中信号处理的问题并重写代码来纠正它。我了解了信号的一般概念,但在实现它们时遇到了很多困难。我不确定 child.c 中的 procmask 是否正常工作,我对信号不太满意,但我不明白为什么你要把 NULL 作为最后一个参数,所以也许这就是错误的部分原因?有人可以指出我正确的方向并让我了解代码的哪一部分是错误的以及原因吗?

父级.c

#include <unistd.h>
#include <signal.h>
int
main(int argc, char *argv[])
{
    pid_t pid;
    sigset_t set;

    sigemptyset(&set);

    sigaddset(&set, SIGUSR1);

    sigprocmask(SIG_BLOCK, &set, NULL);

    pid = fork();

    if (pid == 0) {
        execlp("./child", "./child", NULL);
    }

    while (1) {
        kill(pid, SIGUSR1);
    }

    return (0);
}

子.c

#define _XOPEN_SOURCE 500

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

static void
handler(int signo)
{
    printf("This is the SIGUSR1 signal handler!\n");
}

int
main(void)
{
    sigset_t set;

    sigemptyset(&set);

    sigset(SIGUSR1, handler);

    sigprocmask(SIG_SETMASK, &set, NULL);

    while (1) {
        printf("This is main()!\n");
    }

    return (0);
}

最佳答案

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

最后一个参数用于存储旧的信号掩码。当它为NULL时,意味着我们不需要存储旧的信号掩码。

请注意,您不应在信号处理程序中使用 printf,因为它不可重入,请参阅 How to avoid using printf in a signal handler?

并且execlp的用法是错误的,因为NULL可以被定义为0,编译器可能认为它是一个整数,而不是空指针。

execlp("./child", "./child", NULL);

最后一个参数应该是(char *)0,如下所示:

execlp("./child", (char *)0);

关于c - 父进程正在向子进程发出信号,但子进程的信号处理需要改进,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18057347/

相关文章:

c - 当动态内存分配显式转换为结构类型时,到底会发生什么?

对 error() 的 Python C API 调用绑定(bind)到 libc 实现而不是本地实现

linux - ssh 上的 sed 不会转义反斜杠

python - 无法在 Amazon Linux : invalid syntax 上安装 gcloud

c - 将自定义函数设置为所有信号的处理程序

python - mousepress事件的问题

c - Strcpy 在同一上下文中第二次使用时崩溃了

c - 如何使用 VBO 绘制三角形?

c - 使用和不使用 Scatter/Gather 操作的零拷贝

c - epoll 事件不会引发 SIGIO