2011-07-05 21 views
2

我想从一个线程向进程中的所有其他线程广播信号。接收该信号的线程应处理信号处理程序中的信号。我怎样才能做到这一点?将信号广播到Linux中的所有线程


我试过下面的代码,但它通过打印用户定义的信号1退出。发生了什么事?

#include <stdio.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <pthread.h> 

const int NTHREADS = 4; 

long prev_fact, i; 

void SIGhandler(int);  

void SIGhandler(int sig) 
{ 
    printf("\nThread %lx Received a SIGUSR1.\n", pthread_self()); 
} 

void* tfunc(void* arg) 
{ 
    printf("Thread %lx executing...\n", pthread_self()); 

    while(1) 
    ; 
} 

int main() 
{ 
    int i; 
    pthread_t t[NTHREADS]; 

    for(i = 0; i < NTHREADS; i++) 
    pthread_create(&t[i], NULL, tfunc, NULL); 

    for(i = 0; i < NTHREADS; i++) 
    pthread_kill(t[i], SIGUSR1); 

    for(i = 0; i < NTHREADS; ++i) 
    pthread_join(t[i], NULL); 

    return 0; 
} 

回答

0

下面的代码工作现在...

#include <stdio.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <pthread.h> 

const int NTHREADS = 4; 

void SIGhandler(int);  

void SIGhandler(int sig) 
{ 
    printf("\nThread %lx Received a SIGUSR1.\n", pthread_self()); 
} 

void* tfunc(void* arg) 
{ 
    printf("Thread %d(%lx) executing...\n", *((unsigned int*)arg), pthread_self()); 

    while(1) 
    ; 
} 

int main() 
{ 
    int i; 
    int tid[NTHREADS]; 
    pthread_t t[NTHREADS]; 

    signal(SIGUSR1, SIGhandler); 

    for(i = 0; i < NTHREADS; i++) 
    { 
    tid[i] = i; 
    pthread_create(&t[i], NULL, tfunc, tid+i); 
    } 

    for(i = 0; i < NTHREADS; i++) 
    pthread_kill(t[i], SIGUSR1); 

    for(i = 0; i < NTHREADS; ++i) 
    pthread_join(t[i], NULL); 

    return 0; 
} 
+0

请注意,你写这个的方式,它并不表示主线程本身(在主线程中使用'pthread_self()'来获得它的线程句柄)。 – caf

4

便携式并行线程的方式做,这是周围的所有线程的循环,为每一个执行pthread_kill()。这要求您维护表示过程中每个线程的所有pthread_t值的列表。

在Linux上,你可以阅读/proc/self/task来确定每个线程的TID的当前进程,然后使用tgkill()信号它们(使用getpid()结果作为tgid参数tgkill())。

请注意,glibc不提供tgkill()的包装 - 您必须使用syscall()来调用它。

+0

我尝试下面的代码,但它退出通过打印用户自定义信号1.这是怎么回事? void SIGhandler(int sig) printf(“\ nThread%lx Received a SIGUSR1。\ n”,pthread_self()); (“线程%lx正在执行... \ n”,pthread_self());}} while(1) ; } int main() { int i; pthread_t t [NTHREADS]; (i = 0; i MetallicPriest

+0

我已将代码添加到下面的答案中。你能不能告诉我它有什么问题? – MetallicPriest

+2

@MetallicPriest:您必须使用'sigaction()'注册您的信号处理函数。你只需要做一次,因为信号处置是在所有线程中共享的。 – caf