2011-12-27 93 views
1

pthread_create的手冊頁中,它說:「新線程的未決信號集爲空」。 但我寫了一些測試代碼,得到了相反的結果,即新創建的線程的信號未決列表不爲空。代碼如下:新創建線程的信號掛起列表不是空的?

void* thread_fun(void* arg) 
{ 
    int s; 
    sigset_t pendingset; 

    s = sigemptyset(&pendingset); 
    if(s != 0) 
    { 
     printf("sigempty error.\n"); 
    } 
    else{ 
     s = sigpending(&pendingset); 
     if(s == 0){ 
      if(sigismember(&pendingset, SIGINT)) 
       printf("SIGINT in pending signal list.\n"); // this msg is printed 
     } 
    } 

    return NULL; 
} 

int main() 
{ 
    pthread_t tid; 
    sigset_t set; 
    sigemptyset(&set); 
    sigaddset(&set, SIGINT); 
    pthread_sigmask(SIG_BLOCK, &set, NULL); 

    sleep(10); // send SIGINT to the process using kill -SIGINT pid 
    printf("before create thread...\n"); 
    pthread_create(&tid, NULL, thread_fun, NULL); 

    pthread_join(tid, NULL); 

    return 0; 
} 

在睡眠期間,我將SIGINT發送給進程。由於包含SIGINT的sigmask集合,此時接收到的SIGINT信號在信號列表中處於未決狀態。在pthread_create之後,在新線程中,sigpending返回調用線程的掛起信號,並且SIGINT包含在set中。所以它與手冊頁不一致。

任何幫助表示讚賞。

回答

1

我認爲問題在於你發送的信號是一個進程級別的信號,所以它正等待整個進程(以及所有阻塞它的線程),無論它是否在創建線程之前掛起。所述docs for sigpending()說(強調):

sigpending()功能必須存儲,在由設置參數,該組的從輸送被阻塞調用線程和該信號引用的位置是在該過程掛起或調用線程。

如果調用pthread_create()時掛起的信號是線程級別的信號,那麼它將不會在新創建的線程上掛起。您可以使用pthread_kill(pthread_self(), SIGINT)函數發送信號來測試。

我的確同意有關待處理信號清除新線程的措辭並不十分清楚。

+0

謝謝你的回答。而且我還可以從die中的sigpending()手冊頁找到解釋:待處理線程的一組信號是待處理線程的信號集合和待處理的信號集合整個過程 – Avalon 2011-12-28 01:18:26