我正试图深入研究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;
}
答案 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。