2016-12-12 5 views
2

これは条件変数とmutexの一般的なことをテストするために作成したコードです。それはちょうど10に数えられると考えられていますが、何らかの理由でワーキングスレッドがprintlock mutexで停止し続けることがあります。なぜなら、メインスレッドはprintcondで待機するときに目を覚まさないからです。 これは私の出力です:linuxの条件変数のロック解除c

"I have this many threads: 7 
This is my 1 time running, and my number is 0! 
This is my 2 time running, and my number is 1!" 

私は条件変数についてかなり何かを明らかに不足している必要があります。 printcondを通知した後、ワーカースレッドでprintlockのロックを解除しようとしましたが、コードが実行されますが、メインスレッドは最後の値だけを出力します。私はすべての1-10の "私が得た数"を印刷するメインスレッドをします。それ、どうやったら出来るの?私はこの物の論理構造を理解することができず、私はどこでも解決策を探してきました。どんな助けもありがとうございます。

pthread_mutex_t varlock; 
pthread_mutex_t printlock; 
pthread_cond_t printcond; 

void *worker(void *args) 
{ 
int * count = args; 
int run = 1; 
while(1==1) 
{ 
    pthread_mutex_lock(&varlock); 
    if(*count == 10) 
    { 
     pthread_mutex_unlock(&varlock); 
     printf("I am a thread exiting\n"); 
     return NULL; 
    } 
    else 
    { 
     printf("This is my %d time running, and my number is %d!\n", run, *count); 
     pthread_mutex_lock(&printlock); 
     pthread_cond_signal(&printcond); 
     *count = *count +1; 
     run++; 
    } 
    pthread_mutex_unlock(&varlock); 
} 
} 

int main(int argc, char **argv) 
{ 
int num = 7; 
printf("I have this many threads: %d\n", num); 
int * count = malloc(sizeof(int)); 
*count = 0; 
if (pthread_mutex_init(&varlock, NULL) != 0) 
{ 
    printf("mmult: Failed initializing mutex\n"); 
    return 1; 
} 
if (pthread_mutex_init(&printlock, NULL) != 0) 
{ 
    printf("mmult: Failed initializing mutex\n"); 
    return 1; 
} 
pthread_mutex_lock(&printlock); 
int err=pthread_cond_init(&printcond, NULL); 
//Create the threads 
pthread_t tid[num]; 
int i; 
for(i = 0; i < num; i++) 
{ 
    err = pthread_create(&(tid[i]),NULL,worker, count); 
    if(err) 
    { 
     perror("mmult: Failed creating thread\n"); 
     return 1; 
    } 
} 
while(1==1) 
{ 
    if(*count == 10) 
    { 
     break; 
    } 
    pthread_cond_wait(&printcond, &printlock); 
    printf("The number I got is %d.\n", *count); 
    pthread_mutex_unlock(&printlock); 
} 
//Join all the threads 
int status; 
for(i = 0; i < num; i++) 
{ 
    pthread_join(tid[i],(void **)&status); 
} 
printf("Now that I have finished, the count is %d.\n", *count); 
return 0; 
} 
+0

について 'pthread_cond_wait'(と' pthread_cond_timedwait')について*これらは呼び出し元のスレッドによってロックされたmutexで呼び出されるか、未定義の動作になります。言い換えると、最初に渡すmutexをロックする必要があります。 – ikegami

答えて

1

あなたは多くのバグがありますが、最も明白な1は2番目のwhile(1==1)ループがミューテックスをアンロックするが、それをロックしないということです。だからあなたがループするなら、すでにロックされていないミューテックスをアンロックします。それはバグです。

最初のwhile(1==1)ループもバグです。ミューテックスをただちにロックするには、そのミューテックスをロック解除します。その目的は何と思いますか?

+0

ええ、私は多くのバグを持っています、それはちょうど非常に荒いテストであるはずです。しかし、ポインタをありがとう。 :) –

+1

あなたはそれが動作することを期待する前に、すべてのバグを修正する必要があります。 ;) –

+0

また、 'worker()'関数のループは 'printlock'ミューテックスをロックしますが、決してロックを解除しません。 –