pthread_cond_wait 取りこぼし?
はじめまして。
pthreadのお勉強がてら、パイプライン処理を実装してみようととりあえず実証コードを書いてみましたが、うまく意図した動きをしてくれません。
やりたいことは、処理ステージが2つあって、メインからステージ1をキックし、ステージ1は自分の処理が終わったらステージ2をキックするといった動作です。(メイン、ステージ1、ステージ2を並列に動作させたい)
取りあえず連鎖的に動作するか試したいだけなので、ステージ間のデータの受け渡しとかは、後で考えるとします。
それで、以下のような単純なコードを書きました。
期待する結果は、最後に表示される数値が 10000, 10000, 10000 になることですが、実際は、10000, 4401, 4401 のようにステージ1,2が少なくなります。
一応、それなりに調べて条件変数のセオリーに従い書いたつもりなのですが、どうしてこうなるか、ご教授ください。
test.c (空白を全角にしてあります)
------
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
pthread_mutex_t mutex1,
mutex2;
pthread_cond_t cond1,
cond2;
int ready1,
ready2;
int end1,
end2;
int count1,
count2;
void * stage1( void *arg )
{
pthread_mutex_lock( &mutex1 );
while( 1 ) {
/* wait for my signal & job */
while ( ready1 == 0 ) {
pthread_cond_wait( &cond1, &mutex1 );
}
if ( end1 == 1 ){ /* is shutdown thread */
break;
}
/* my job. */
count1++;
/* job clear */
ready1 = 0;
/* forward next stage */
pthread_mutex_lock( &mutex2 );
ready2 = 1;
pthread_cond_signal( &cond2 );
pthread_mutex_unlock( &mutex2 );
}
pthread_mutex_unlock( &mutex1 );
return NULL;
}
void * stage2( void *arg )
{
pthread_mutex_lock( &mutex2 );
while( 1 ) {
while ( ready2 == 0 ) {
pthread_cond_wait( &cond2, &mutex2 );
}
if ( end2 == 1 ){
break;
}
count2++;
ready2 = 0;
}
pthread_mutex_unlock( &mutex2 );
return NULL;
}
int main( )
{
int i;
pthread_t t1,
t2;
pthread_mutex_init( &mutex1, 0 );
pthread_cond_init ( &cond1, 0 );
ready1 = 0;
end1 = 0;
count1 = 0;
pthread_create( &t1, 0, stage1, NULL );
pthread_mutex_init( &mutex2, 0 );
pthread_cond_init ( &cond2, 0 );
ready2 = 0;
end2 = 0;
count2 = 0;
pthread_create( &t2, 0, stage2, NULL );
for ( i=0; i<10000; i++ ){
pthread_mutex_lock( &mutex1 );
ready1 = 1;
pthread_cond_signal( &cond1 );
pthread_mutex_unlock( &mutex1 );
}
pthread_mutex_lock( &mutex1 );
ready1 = 1;
end1 = 1;
pthread_cond_signal( &cond1 );
pthread_mutex_unlock( &mutex1 );
pthread_join(t1, 0 );
pthread_cond_destroy( &cond1 );
pthread_mutex_destroy( &mutex1 );
pthread_mutex_lock( &mutex2 );
ready2 = 1;
end2 = 1;
pthread_cond_signal( &cond2 );
pthread_mutex_unlock( &mutex2 );
pthread_join(t2, 0 );
pthread_cond_destroy( &cond2 );
pthread_mutex_destroy( &mutex2 );
printf("%d, %d, %d\n", i, count1, count2);
return 0;
}
------
gcc -o test -lpthread test.c
以上