2016-08-31 10 views
2

私はマルチスレッドプログラミングの初心者で、pthead_cond_wait()で待機中にシグナルが送信されたとき、その結果はOSによって異なることがわかりました。 誰かがコールがどのように中断されたか、そして移植可能なコードを書く方法を知る方法を教えてもらえますか?文書化されているようにpthread_cond_wait()とsignal、結果はOSに依存する


MacOS X 10.11.4 
cc -o condwait condwait.c -lpthread 

Linux 2.6.32-642.3.1.el6.x86_64 
gcc -o condwait condwait.c -lpthread 

Solaris11 5.11 11.2 
cc -D_POSIX_C_SOURCE -D_REENTRANT -mt -o condwait condwait.c -lpthread 

MacOS X 
$ ./condwait & 
[1] xxxxx 
$ kill -USR1 %1 
signal called 
after pthread_cond_wait : 0 
error pthread_cond_wait:: Unknown error: 260 

Solaris 
$ ./condwait & 
[1] xxxxx 
$ kill -USR1 %1 
signal called 
after pthread_cond_wait : 0 
error pthread_cond_wait : Error 0 

Linux 
$ ./condwait & 
[1] xxxxx 
$ kill -USR1 %1 
signal called 
$ jobs 
[1]+ Running 

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

void 
sigusr1_handler(int sig) 
{ 
    printf("signal called\n"); 
} 

int 
main() 
{ 
    int n; 
    pthread_mutex_t mut; 
    pthread_cond_t cond; 
    struct timespec ts; 

    signal(SIGUSR1, sigusr1_handler); 
    pthread_mutex_init(&mut, NULL); 
    pthread_cond_init(&cond, NULL); 

    pthread_mutex_lock(&mut); 
    printf("before cond_wait\n"); 
    n = pthread_cond_wait(&cond, &mut); 
    printf("after pthread_cond_wait : %d\n", n); 
    perror("error pthread_cond_wait:"); 

    pthread_mutex_unlock(&mut); 
    return 0; 
} 
のSolarisネイティブ cond_wait()を使用して、それが EINTRを返します。 pthread_cond_wait()が中断されたことを知る方法はありますか?

答えて

1

私はそれが言う、Linuxのpthread_cond_waitの男の取扱説明書をお読みください。

信号は、スレッドが条件を待って再開シグナルハンドラからの復帰時に、条件変数を待っているスレッドに配信された場合変数が中断されていないかのように変数を変更するか、偽のウェイクアップのためにゼロを返します。

他のOSにもわかりやすいマニュアルがあります。

+0

親愛なるbarcelona_delpyのような第2のロックが必要になります。 – kaotan

+0

親愛なるbarcelona_delpyさん、あなたの答えに感謝します。私は日本語版のLinuxマニュアルを読んでいます。pthread_cond_timedwaitは、通知されるとEINTRを返します。私はいくつかのマニュアルを探すだろうが、SUS3のマニュアルだけがエラーを返す。それから、MacOS XとSolaris、SUS3で状態を待つ間に信号をブロックする必要があります。よろしくね、 – kaotan

2

POSIXは、この関数が決してEINTRを返さないことを指定します。とにかくそれをチェックすることができるレガシーOSへの移植性のために、それは傷つきません

さらに重要なことに、偽の起床の準備をする必要があります。この関数は、条件が満たされていない何らかの理由でいつでもゼロを返すことができます。ミューテックスはロックされます。条件をチェックしなければならない場合は、pthread_cond_waitに戻ります。

+0

親愛なるn.m.あなたの答えをありがとう。たぶんあなたは私に[pthread_mutex_lock(); while(condition_is_false) pthread_cond_wait(); pthread_mutex_unlock(); ] – kaotan

+0

はいこれがパターンです。 –

0

大変ありがとうございます。 私は長い待機状態を停止するために信号を使用すると動作しないことを知っています。 pthread_cond_wait()は、中断されていないかのように条件を待機し続けるか、擬似ウェークアップのためにゼロを返します。 はその後、私はそれをしたい、私はあなたが答えてくれてありがとう、

pthread_mutex_lock(&mut); 
while(condition_is_false) { 
    n = pthread_cond_timedwait(); 
    if (n == ETIMEDOUT) { 
    pthread_mutex_lock(&mut2); 
    if (condition2_is_true) { 
     pthread_mutex_unlock(&mut2); 
     pthread_mutex_unlock(&mut); 
     return STOPPED; 
    } 
    pthread_mutex_unlock(&mut2); 
    } 
} 
pthread_mutex_unlock(&mut); 
return 0; 

よろしく、

関連する問題