libevent支持在观看信号到达时通知。似乎信号可以在Linux / Unix上的任何代码处中断(是不是?)。这是否意味着,我应该在调用所有系统调用和其他库函数后检查返回值并且errno
等于EINTR
?
有简单的测试代码。
#include <stdio.h>
#include <signal.h>
int i = 0;
void handle(int signo)
{
printf("i[%d], signo[%d]\n", i, signo);
}
int main()
{
signal(SIGINT, handle);
while (1) {
i++;
}
return 0;
}
运行此代码后,按几个 Ctrl + C ,得到以下输出:
./signal
^Ci[475151517], signo[2]
^Ci[656118185], signo[2]
^Ci[891673397], signo[2]
^Ci[1668347228], signo[2]
^Ci[-2123628990], signo[2]
似乎sigint
在i++
处中断。如果上面的猜想是正确的,那么处理信号的正确方法是这样的:
pthread_sigmask
来阻止运行事件循环的主线程中的信号。sigwait
等待观察线程中的信号,并通过管道通知主线程。谢谢!
答案 0 :(得分:0)
是的,一个信号可以在任何地方中断执行(除非被屏蔽),是的,它意味着所有系统调用(我不确定是否有一些例外?),例如写入/读取/轮询将在被中断时返回EINT信号(您可能想要阅读man page for pselect,特别是'BUGS'部分)。这称为'PC loser-ing problem'
您应该使用libevent原生支持进行信号处理。查看所有宏'evsignal_xxx'in their documentation。
简而言之,您可以这样做:
struct event ev_sigint;
struct event_base *ev_base;
ev_base = event_init();
evsignal_set(&ev_sigint, SIGINT, sighandler, ev_base);
evsignal_add(&ev_sigint, NULL);
event_dispatch();
然后从信号处理程序中断开循环:
void sighandler(int signal, short events, void *base)
{
event_base_loopbreak(base);
}