2017-05-05 16 views
0

我使用多個線程處理應用程序。其中一個用於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'歸零)而不是「信號」,做事情的工作? –

回答

0

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