获取是否收到信号

时间:2016-02-06 20:36:47

标签: c signals

如果流程收到信号,如何获得?以下示例的目的是分叉进程,使用子进程读取字符并将SIGUSR1发送给父进程,但是如果用户仍然需要插入字符10秒后,子进程将终止。问题是如何知道是否收到SIGUSR1:

#define _POSIX_SOURCE

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>

void handle_USR1()
{
    return;
}

int main(void)
{
    int p[2];
    pid_t pid;

    if(pipe(p) == -1)
    {
        perror("pipe");
        return -1;
    }

    if((pid = fork()) == -1)
    {
        perror("fork");
        return -1;
    }

    if(pid == 0)
    {
        close(p[0]);
        char ch, b;

        ch = getchar();

        if(ch != '\n')
            while((b = getchar()) != '\n' && b != EOF);

        write(p[1], &ch, 1);
        kill(getppid(),SIGUSR1);

        exit(-1);
    }
    else
    {
        signal(SIGUSR1,handle_USR1);
        close(p[1]);
        char ch;

        sleep(10);
        kill(pid, SIGTERM);

        read(p[0],&ch,1);

        //if(/*SIGUSR1 is not recived*/)
        //{
        //    exit(-1);
        //}

        printf("\n\n%c",ch);
    }

    return 0;
}

我可以用{<1}}取代什么?

2 个答案:

答案 0 :(得分:3)

comment中,我建议:

  

您的handle_USR1()函数应将static volatile sig_atomic_t变量设置为已知值(例如1)。然后,您可以检查该变量以了解是否已收到信号。在标准C中,您可以在信号处理程序中以严格符合的方式执行其他操作;在POSIX中,你可能会做更多的事情(但要小心:Avoid using printf() in a signal handler可以帮助你)。

这就是我的意思,根据您的代码密切转换为代码:

sigusr1.c

#define _POSIX_SOURCE

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

static volatile sig_atomic_t sig = 0;

static void handle_USR1(int signum)
{
    sig = signum;
}

int main(void)
{
    int p[2];
    pid_t pid;

    signal(SIGUSR1, handle_USR1);

    if (pipe(p) == -1)
    {
        perror("pipe");
        return -1;
    }

    if ((pid = fork()) == -1)
    {
        perror("fork");
        return -1;
    }

    if (pid == 0)
    {
        close(p[0]);
        char ch, b;

        ch = getchar();

        if (ch != '\n')
            while ((b = getchar()) != '\n' && b != EOF)
                ;

        write(p[1], &ch, 1);
        kill(getppid(), SIGUSR1);

        exit(-1);
    }
    else
    {
        close(p[1]);
        char ch;

        sleep(10);
        if (sig != 0)
            printf("Signal number %d received while sleeping\n", sig);
        else
        {
            printf("Sending SIGTERM to child %d\n", (int)pid);
            kill(pid, SIGTERM);
        }

        if (read(p[0], &ch, 1) == 1)
            printf("Character sent by child: [%c]\n", ch);
        else
            printf("No data sent by child before it died\n");
    }

    return 0;
}

汇编

Mac OS X上的GCC 5.3.0 10.11.3 El Capitan:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
>     -Wold-style-definition -Werror sigusr1.c -o sigusr1
$

样本输出

$ ./sigusr1
Sending SIGTERM to child 70657
No data sent by child before it died
$ ./sigusr1
Kaput
Signal number 30 received while sleeping
Character sent by child: [K]
$

答案 1 :(得分:0)

请chek man 2 signal给出以下摘要

#include <signal.h>

   typedef void (*sighandler_t)(int);

   sighandler_t signal(int signum, sighandler_t handler);

使用signal注册处理程序,处理程序的类型为

 void handler(int signum) {
     //do whatever you like
 }

这里param sugnum接收信号编号。在你的情况下它SIGUSR1并且可以在句柄内以确定它是哪个信号