2017-07-29 129 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个试验组中有所不同)进入子线程,休息到达主线程。 –