父进程在子进程中触发信号,但需要改进子进程的信号处理

时间:2013-08-05 11:45:34

标签: c linux signals fork signal-handling

我正在为考试做一些练习题,其中一个问题给出了两段叫做parent.c和child.c的代码。父母创建一个孩子并在其上发出信号,孩子每次收到信号时都会显示一条信息。孩子将花费其余的时间从主要打印消息。问题是描述child.c中的信号处理有什么问题,并重新编写代码来纠正它。我得到了信号的一般概念,但实现它们有很多困难。我不确定child.c中的procmask是否正常工作,我对信号不太满意,但我不明白你为什么要把NULL作为最后一个参数,所以也许这就是为什么这是错的?有人可以指出我正确的方向,让我知道代码的哪一部分是错的,为什么。

Parent.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);
}

Child.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);
}

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

由于man sigset状态sigset已过时,您应使用sigactionHere是如何使用它的示例。