_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); 
+0

你如何“抓住'SIGINT'信号”? –

+0

@KerrekSB,我已经更新了这个问题 – Leonid

+1

如果你使用['sigaction'](http://man7.org/linux/man-pages/man2/sigaction.2.html)('sa_flags'归零)而不是“信号”,做事情的工作? –

在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 sigactionsa_flagsSA_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具有未指定的行为。