- ベストアンサー
pthread_cond_waitとptherad_cond_signal
pthread_cond_waitで寝ているthreadに対して、ptherad_cond_signalにて起こして、そのthreadが再度寝るまでの間にpthread_cond_signalが複数回(2回として)Callされた場合、どのような挙動になるのでしょうか? 最初のSignalをA、以下B,Cとすると A->cond_wait->B->cond_wait->C となるのでしょうか? 宜しくお願い致します。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
>waitしていたthreadが稼動している状態でのsignal発行は空振りに終わるということでしょうか? その通りです。 ptherad_cond_signalが発行されたとき、pthread_cond_waitで待機しているスレッドがなければ、そのシグナルは無視されます。 参考までに下記の実験結果を参照下さい。(空白は全角にしてます) ソースプログラム ------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <time.h> pthread_mutex_t mut_sub_print = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mut_sub_th = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond_sub_th = PTHREAD_COND_INITIALIZER; int main_sleep_time; int sub_sleep_time; void sub_print(char *name,char *msg,int ctr) { pthread_mutex_lock(&mut_sub_print); printf("%s:%s(%d)\n",name,msg,ctr); fflush(stdout); pthread_mutex_unlock(&mut_sub_print); } void *sub_thread(void *adddr) { int ctr = 0; pthread_mutex_lock(&mut_sub_th); while(1){ pthread_cond_wait(&cond_sub_th,&mut_sub_th); ctr++; sub_print("sub","con_wait終了",ctr); usleep(sub_sleep_time*1000); } return NULL; } // 第1パラメータにメインスレッドのスリープ時間(ミリ秒) // 第2パラメータにサブスレッドのスリープ時間(ミリ秒) int main(int argc,char **argv) { int ret; int i; int ctr = 0; pthread_t tid; if (argc != 3){ printf("%s P1 P2\n",argv[0]); printf("P1:メインスレッドのスリープ時間(ミリ秒)\n"); printf("P2:サブスレッドのスリープ時間(ミリ秒)\n"); exit(1); } main_sleep_time = atoi(argv[1]); sub_sleep_time = atoi(argv[2]); printf("メインスリープ時間=%dミリ秒\n",main_sleep_time); printf("サブスリープ時間=%dミリ秒\n",sub_sleep_time); ret = pthread_create(&tid,NULL,sub_thread,NULL); if (ret != 0){ printf("pthread_create error:%d\n",ret); exit(1); } usleep(1000); //1ミリ停止 for (i = 0; i < 10; i++){ ctr++; pthread_cond_signal(&cond_sub_th); sub_print("main","cond_signal完了",ctr); usleep(main_sleep_time*1000); } sleep(10); sub_print("main","スレッド停止",0); exit(0); } --------------------------------------------- 第一引数にメインスレッドのスリープ時間 第二引数にサブスレッドのスリープ時間を指定します。 メインスレッド側で、スリープ時間を大きくとり、ゆっくりと cond_signalを発行すると、空振りが起こりにくくなります。 逆にメインスレッド側で、スリープ時間を小さく取り、 cond_signalを速射すると、空振りが起こりやすくなります。 以下、実行結果。 メインスレッド:300ミリのスリープ サブスレッド:100ミリのスリープの場合 cond_signal 300 100 メインスリープ時間=300ミリ秒 サブスリープ時間=100ミリ秒 main:cond_signal完了(1) sub:con_wait終了(1) main:cond_signal完了(2) sub:con_wait終了(2) main:cond_signal完了(3) sub:con_wait終了(3) main:cond_signal完了(4) sub:con_wait終了(4) main:cond_signal完了(5) sub:con_wait終了(5) main:cond_signal完了(6) sub:con_wait終了(6) main:cond_signal完了(7) sub:con_wait終了(7) main:cond_signal完了(8) sub:con_wait終了(8) main:cond_signal完了(9) sub:con_wait終了(9) main:cond_signal完了(10) sub:con_wait終了(10) main:スレッド停止(0) メインスレッド:100ミリのスリープ サブスレッド:300ミリのスリープの場合 cond_signal 100 300 メインスリープ時間=100ミリ秒 サブスリープ時間=300ミリ秒 main:cond_signal完了(1) sub:con_wait終了(1) main:cond_signal完了(2) main:cond_signal完了(3) main:cond_signal完了(4) sub:con_wait終了(2) main:cond_signal完了(5) main:cond_signal完了(6) main:cond_signal完了(7) sub:con_wait終了(3) main:cond_signal完了(8) main:cond_signal完了(9) main:cond_signal完了(10) sub:con_wait終了(4) main:スレッド停止(0)
その他の回答 (1)
- tatsu99
- ベストアンサー率52% (391/751)
結論から言えば、そうなる場合もあるし、ならない場合もある。となります。 ptherad_cond_signalを発行したときに、pthread_cond_waitで寝ているスレッドが存在しない場合、そのcond_signalの発行は、空振りに終わります。
補足
質問した内容の状況、waitしていたthreadが稼動している状態でのsignal発行は空振りに終わるということでしょうか?
お礼
再度の御回答ありがとうございます。 丁寧にソースコードまで提供していただき、恐縮です。。。 大変良くわかりました。 ありがとうございました。