_GNU_SOURCE宏和epoll_wait行为
我使用多个线程处理应用程序。其中一个用于epoll。这个应用程序还捕获SIGINT
信号并执行一些定稿。一切工作理想,直到我设置_GNU_SOURCE
宏。这使得程序来卡住就行了:_GNU_SOURCE宏和epoll_wait行为
int n = epoll_wait(epfd, events, N, -1);
因此,设置_GNU_SOURCE
阻止所有(recv
太)从打破SIGINT
等待呼叫。为什么这样?什么是解决方法?我想用sched_setaffinity
。这需要CPU_SET
,只有_GNU_SOURCE
可用。
UPDATE
我如何赶上SIGINT
:
static volatile int running = 1;
static void int_handler(int i) {
running = 0;
}
然后在main
:
signal(SIGINT, int_handler);
在GNU/Linux,大多数非内核头文件的/usr/include
是由提供glibc的相同包提供。当glibc提供了函数的多个实现时,可以使用feature_test_macros(如_GNU_SOURCE
)在各种实现中进行选择。
当您定义_GNU_SOURCE
时,它也定义了_BSD_SOURCE
,并且在更新版本的glibc上,_DEFAULT_SOURCE
。当定义这些宏时,头文件将安排给你一些函数的BSD版本。 signal是这些功能之一。
在各种UNIX下,signal
做的事情略有不同。您遇到的不同之处:发送信号时某些“慢”系统调用被中断时会发生什么情况。在处理程序返回后,在V7和System III(和System V)上,系统调用将返回一个EINTR
错误。在4.2BSD上,系统调用将被重新启动。
如果使用POSIX标准sigaction,而不是signal
,您可以选择系统调用是否重新启动或不设置或清除从struct sigaction
的sa_flags
的SA_RESTART
标志。
在glibc的2.19的signal
卷起System V的版本调用sigaction
用旗帜SA_RESTORER|SA_INTERRUPT|SA_NODEFER|SA_RESETHAND
和BSD版本调用sigaction
与标志SA_RESTORER|SA_RESTART
。
使用sigaction
的另一个原因:正如@KerrekSB指出的,在多线程应用程序中使用signal
具有未指定的行为。
你如何“抓住'SIGINT'信号”? –
@KerrekSB,我已经更新了这个问题 – Leonid
如果你使用['sigaction'](http://man7.org/linux/man-pages/man2/sigaction.2.html)('sa_flags'归零)而不是“信号”,做事情的工作? –