`c`中的信号。 while循环的使用

时间:2016-05-09 05:15:23

标签: c signals

我正试图深入研究C中的信号并试图了解它是如何工作的。我知道SIGKILL和SIGSTOP无法处理/捕获。我的问题是,任何人都可以在下面的代码中解释while-loop的作用吗?如果没有while循环怎么办。

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

void sig_handler(int signo)
{
    if (signo == SIGUSR1)
        printf("received SIGUSR1\n");
    else if (signo == SIGKILL)
        printf("received SIGKILL\n");
    else if (signo == SIGSTOP)
        printf("received SIGSTOP\n");
}

int main(void)
{
    if (signal(SIGUSR1, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGUSR1\n");
    if (signal(SIGKILL, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGKILL\n");
    if (signal(SIGSTOP, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGSTOP\n");
    // A long long wait so that we can easily issue a signal to this process
    while(1) 
        sleep(1);
    return 0;
}

2 个答案:

答案 0 :(得分:2)

while循环永远调用sleep(1)。直到它被信号中断,此时进程将停止休眠,运行信号处理程序,然后在/当信号处理程序返回时再次休眠。

我建议将其更改为循环内的sleep(UINT_MAX)。该程序具有相同的行为,但效率更高,因为代码不需要每秒在用户和内核模式之间转换。

答案 1 :(得分:2)

我假设您使用的是Linux或某些POSIX系统。

然后,仔细阅读 signal(7)。请注意,信号处理程序只能调用异步信号安全函数,而printf 不是这样的函数。所以你的代码有undefined behavior,所以非常错误。

阅读有关<signal.h>的POSIX文档。您可能需要定义全局volatile sig_atomic_t flag;并将其设置在信号处理程序中(并在外部测试,例如在event loop上方的某些poll(2))。

while(1) 
    sleep(1);

只是围绕sleep(3)函数的无限循环,在循环体中等待一秒钟(例如,对于要发送的信号;该信号将“中断”当前对sleep的调用,但是循环将重新开始,除非信号终止过程。)

您还可以在程序中使用strace(1)来了解涉及的系统调用。

顺便说一句,你可以小心地循环sigsuspend(2)(而不是sleep)。

我还建议阅读Advanced Linux Programming