2016-07-06 55 views
1

在我的程序中,我期望線程A定期發送SIGUSR1到線程B.在線程B中,它將阻塞在sigwait。至於收到SIGUSR1時該怎麼辦,我還沒有定義它。以下是我的代碼。但是,程序立即終止,輸出爲User defined signal 1pthread信號不起作用

void usr1_handler(); 

int main(int argc, char const *argv[]) 
{ 
    pthread_t tid; 
    pthread_attr_t attr_obj; 
    void *thread(void *); 

    pthread_attr_init(&attr_obj); 
    pthread_attr_setdetachstate(&attr_obj, PTHREAD_CREATE_DETACHED); 
    pthread_create(&tid, &attr_obj, thread, (void *)NULL); 

    while(1) 
    { 
    int ret = pthread_kill(tid, SIGUSR1); 
    sleep(5); 
    } 
    return 0; 
} 

void *thread(void *dummy) 
{ 
    int sig; 
    sigset_t sigmask;     
    struct sigaction action; 

    /* set up signal mask to block all in main thread */ 
    sigfillset(&sigmask); 
    pthread_sigmask(SIG_BLOCK, &sigmask, (sigset_t *)0); 

    for (;;) 
    { 
    int err = sigwait(&sigmask, &sig); 
     /* define what to do with sig here */ 
    printf("sig is %d\n", sig); 
    } 

    pthread_exit((void *)NULL); 
} 
+1

'SIGUSR'信號可能在子線程阻塞所有信號並達到'sigwait()'之前傳遞。 –

+0

@AndrewHenle感謝您的回覆。但是主線程會永遠在while(1)循環中發送信號,即使第一個信號丟失,其餘的仍然會傳送,對嗎? – HuangJie

+0

@黃傑如果這確實是發生了什麼,你的程序在第一個信號發送後已經崩潰了 –

回答

0

你做錯了。您明確安排SIGUSR1在線程中解除封鎖,但這確實是錯誤的做法。一些文檔不明確(例如,Linux聯機幫助頁sigwait()),但POSIX says

通過set定義的信號應具有在呼叫到sigwait()的時間被阻止;否則,行爲是不確定的。

(着重號。)

不要忽視@ AndrewHenle的和@ 2501的關於競爭條件的意見,但是。你也有。我同意@ 2501,解決這個問題的最簡單方法是在主線程中設置信號掩碼,以便另一個繼承它。不要在啓動另一個線程後恢復主線程的信號掩碼,但是,否則你可能會發現你的程序很難被殺死。

+0

相關:http://stackoverflow.com/questions/6326290/about-the-ambiguous-description-of-sigwait –

0

目前沒有任何阻止的主要功能從調用pthread_kill創建的線程設置其信號處理之前。在主函數調用之前確保對sigfillset等的調用已完成:int err = sigwait(&sigmask, &sig);

既然你已經使用並行線程,使用互斥和共享標誌變量:

最簡單的方法是將信號處理,從功能到threadmain,呼叫給pthread_create之前。