2017-07-29 196 views
1

信號可以在任何線程中接收到的主線程(主程序)或主要程序本身。 我從主程序創建了一個輔助線程。所以在我的程序中有兩個線程1.主線程(進程本身)2.輔助線程。我只是希望每當信號到達我的輔助線程時,就應該發送信號給我的主線程(程序)。我正在使用pthread_kill(main_threadid,sig)從輔助線程內的信號處理程序寄存器發送信號。但。我觀察到每個時間信號發送到主線程接收到的輔助子本身和信號處理器落在接收發送信號的環路中。pthread_kill()不發送信號到

#include <pthread.h> 
#include <signal.h> 
#include <stdio.h> 
#include <unistd.h> 

// global variable 
pthread_t main_threadId; 
struct sigaction childpsa; 

// Signal Handler for Auxiliary Thread 
void signalHandler_Child(int param) 
{ 
    printf("Caught signal: %d in auxiliary Thread", param); 
    pthread_kill(main_threadId, param); 
} 

void *childFun(void *arg) 
{ 
    childpsa.sa_handler = signalHandler_Child; 
    sigaction(SIGTERM, &childpsa, NULL); 
    sigaction(SIGHUP, &childpsa, NULL); 
    sigaction(SIGINT, &childpsa, NULL); 
    sigaction(SIGCONT, &childpsa, NULL); 
    sigaction(SIGTSTP, &childpsa, NULL); 

    while (1) { 
     // doSomething in while loop 
    } 
} 

int main(void) 
{ 
    main_threadId = pthread_self(); 

    fprintf(stderr, "pid to signal %d\n", getpid()); 

    // create a auxiliary thread here 
    pthread_t child_threadId; 
    int err = pthread_create(&child_threadId, NULL, &childFun, NULL); 

    while (1) { 
     // main program do something 
    } 

    return 1; 
} 

說我發送SIGINT從終端使用其進程ID處理。

+1

我不太確定你想要做什麼,但使用全局信號,線程間通信可能是不正確的方法。 – thrig

回答

2

從UNIX環境高級編程:

每個線程都有自己的信號掩碼,但信號處置由進程中的所有線程共享。這 意味着各個線程可以阻止信號,但是當一個線程修改與給定 信號相關聯的動作,所有線程共享的動作。因此,如果一個線程選擇忽略給定的信號,另一個線程可以通過恢復默認配置或爲信號安裝信號處理程序來撤消該選擇。

sigaction調用是爲整個進程(以及該進程中的所有線程)設置信號處置。

當你發送一個信號的過程中,還沒有阻塞信號,任何線程(但只有1個線程),可以接收它(儘管從我有限的經驗主線程通常是首選)。在您的代碼中,主線程可能會獲取信號,運行信號處理程序,然後再將信號立即發送給自己。

如果您希望您的一個輔助線程來處理你的過程中的所有信號,您可以用pthread_sigmask在主線程阻塞問題的信號:

sigset_t set; 
sigemptyset(&set); 
sigaddset(&set, SIGTERM); 
sigaddset(&set, SIGHUP); 
sigaddset(&set, SIGINT); 
sigaddset(&set, SIGCONT); 
sigaddset(&set, SIGTSTP); 
pthread_sigmask(SIG_BLOCK, &set, NULL); 

這將確保信號不交付給該線程。如果您在pthread_create之前執行此操作,則需要在輔助線程中解鎖它們。

然後,您可以使用無信號的線程間通信機制回來傳達給主線程。

+0

感謝您對信號配置和信號掩碼的澄清,主要是「信號調用爲整個過程設置信號配置」。我只是不想在輔助線程中接收信號,只想要在主線程中接收所有信號,所以我只是在子線程中使用pthread_sigmask來阻塞所有信號。現在我可以看到(使用信號處理程序)所有信號只接收到主線程(Thats Great !!)。但作爲快,我從終端使用while循環發送相同的信號,所有信號在主線程recevied(沒關係),但我並沒有從終端 –

+0

嗨史蒂芬收到的所有sended信號,你是正確的「主線程有可能得到信號,運行信號處理程序,然後再次將信號發送給自己。「 在我的系統中,對於100個信號試驗,25個信號(這個計數在不同的100個試驗組中有所不同)進入子線程,休息到達主線程。 –