• ベストアンサー

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 となるのでしょうか? 宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.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)

f_attck
質問者

お礼

再度の御回答ありがとうございます。 丁寧にソースコードまで提供していただき、恐縮です。。。 大変良くわかりました。 ありがとうございました。

その他の回答 (1)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

結論から言えば、そうなる場合もあるし、ならない場合もある。となります。 ptherad_cond_signalを発行したときに、pthread_cond_waitで寝ているスレッドが存在しない場合、そのcond_signalの発行は、空振りに終わります。

f_attck
質問者

補足

質問した内容の状況、waitしていたthreadが稼動している状態でのsignal発行は空振りに終わるということでしょうか?

関連するQ&A