假设有一个程序,当接收到某个信号时,打印该信号的编号以及ID发送该信号的进程。在代码中,一切看起来像这样:
用作函数的信号处理程序的函数sigaction()
void fun(int sig, siginfo_t *make, void *arg){
printf("Received signal: %d\n", sig);
printf("From process %u\n", make->si_pid);
printf("Done from function\n");
}
还有我自己main()
int main(void)
{
struct sigaction test;
memset(&test, 0, sizeof(test));
printf("I am process %i\n", getpid());
test.sa_sigaction = &fun;
test.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &test, NULL);
sleep(100);
printf("Done from main\n");
return 0;
}
该程序将使用一个信号SIGTERM- 一个请求进程结束的信号。文末会写怎么看程序的输出,不过现在想问几个问题:
1)请告诉我,sigaction()是否为该函数创建了一个单独的进程/线程?我只是不太明白为什么,当我在 main() 中调用这个函数时,它只在收到信号时才执行,而不是在我调用它时立即执行。
2)我不太明白 flag 的含义SIGINFO,但是如果我不设置它,那么答案会有所不同。请解释它的用途(程序/用户)
3)为什么,当控制从一个函数返回到另一个sigaction()函数main()时,程序立即显示该短语Done from main,而不是100在调用函数后等待几秒钟过去sleep()。而如果为 单独创建线程sigaction(),那为什么sleep()接收到信号后会被忽略
程序输出:运行这个程序并记住函数输出到printf()终端的数字,然后打开另一个终端并在那里写入以下命令
kill -SIGTERM <pid>
,其中 pid 是您记住的数字。
ps linux下可以,windows下没试过
printf 不能在信号内部调用。信号处理程序中允许的函数列表。
1)当前线程被挂起,信号处理程序正在其中运行。
2) 当应用程序接收到信号时,可能并非所有关于该信号的信息都可用。而用户需要调用 sigwaitinfo(2) 和 sigtimedwait(2) 来获取。如果设置了 SIGINFO 标志,那么所有这些信息都将立即可用。由于您正在显示有关发送信号的进程的信息,因此最好设置此标志。
3)因为接收到一个信号会中断一些函数(长函数)的执行。睡眠包含在其中。法力上写得很清楚。