2011-07-05 8 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

これを行うには、ポータブルのpthreadsの方法は、それぞれに対してpthread_kill()を実行して、すべてのスレッドの周りのループにあります。これには、プロセスの各スレッドを表すすべてのpthread_t値のリストを維持する必要があります。 Linuxの

、あなたは(tgkill()からtgidパラメータとしてgetpid()の結果を使用)、それらを知らせるためにtgkill()を使用し、その後、現在のプロセス内のすべてのスレッドのTIDをを決定するために/proc/self/taskを読むことができます。

glibcはtgkill()のラッパーを提供しないので、syscall()を使用して呼び出す必要があります。

+0

は、私は、次のコードを試してみましたが、それは何が起こっているユーザー定義信号1を印刷して終了しますか? void SIGhandler(int sig) { printf( "\ nThread%lxはSIGUSR1を受け取りました。\ n"、pthread_self()); } void * tfunc(void * arg) { printf( "スレッド%lx実行中... \ n"、pthread_self()); (1) ; } int main() { int i; pthread_t t [NTHREADS]; for(i = 0; i MetallicPriest

+0

私は以下の回答のコードに追加しました。親切にも何が間違っているのか教えていただけますか? – MetallicPriest

+2

@ MetallicPriest:あなたは 'sigaction()'を使ってシグナル処理関数を登録しなければなりません。信号処理はすべてのスレッドで共有されるため、これを一度だけ行う必要があります。 – caf

関連する問題