2016-10-28 14 views
0
私は現在、次のコードは、次の印刷されません理由として困惑している

理解のpthread

My value is 0 
My value is 1 
My value is 2 

私はこの私を実行するたびにどちらかの1-2印刷された線または何も、プログラムはただ座っを取得私がctrl-cになるまで。 3つのスレッドを持つ同じ条件変数とmutexを使って私と何か関係があるかもしれないような気がしますが、これは正しいでしょうか?説明は大変ありがとうございます。

#include <stdio.h> 
#include <pthread.h> 
#include <assert.h> 
#include <unistd.h> 
#include <stdlib.h> 

struct id_holder 
{ 
int id; 
}; 

pthread_mutex_t intersectionMutex = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t directionCondition = PTHREAD_COND_INITIALIZER; 
struct id_holder * holder; 

void * logic(void* val) 
{ 
    struct id_holder * id_struct = (struct id_holder *) val; 

    pthread_cond_wait(&directionCondition, &intersectionMutex); 
    printf("My value is %d\n", id_struct->id); 
    free(id_struct); 
    return NULL; 
} 

int main(void) 
{ 
    pthread_t threads[3]; 

    for(int i = 0; i <3; i++) 
    { 
     holder = (struct id_holder *) malloc(sizeof(struct id_holder)); 
     holder->id = i; 
     pthread_create(&threads[i], NULL, logic, holder); 
    } 

    for(int i = 0; i < 3; i++) 
    { 
     sleep(1); 
     pthread_cond_signal(&directionCondition); 
    } 

    for(int i = 0; i < 3; i++) 
    { 
     pthread_join(threads[i], NULL); 
    } 

    return 0; 
} 

答えて

3

条件が待っているか、または信号で通知されている場合、ロックの下で実行する必要があります。そうでない場合は、競合状態になる可能性があるため予測できません。

pthread_mutex_lock(&intersectionMutex); 
pthread_cond_wait(&directionCondition, &intersectionMutex); 
pthread_mutex_unlock(&intersectionMutex); 

そして、(必要であれば、あなたがループの外にロックを移動することができます)メインで同じ:

for(int i = 0; i < 3; i++) { 
    sleep(1); 
    pthread_mutex_lock(&intersectionMutex); 
    pthread_cond_signal(&directionCondition); 
    pthread_mutex_unlock(&intersectionMutex); 
} 

はまだコードは100%安全ではありませんので、あなたのコードは次のようになります。メインスレッドは、子スレッドが待機を呼び出す前に条件を通知できます。 main関数のsleep()のためにここではほとんど起こり得ませんが、一般的に、待機が実際に必要かどうかを識別する変数が必要です。つまり、条件はキューではなく、キューを作成するために使用できます。