2016-05-01 12 views
0

Cのpthreadライブラリでは、単純なプロデューサ/コンシューマスキーマを実装しようとしています。プロデューサ/コンシューマキューの不安定なデッドロック

プロデューサーは、乱数を生成し、消費者はただの数字一つ一つを取り、それを標準出力に出力します。この

typedef struct { 
    int q[MAX_QUEUE]; 
    int head; 
    int tail; 
} queue; 

のようにキューに入れます。同期は、mutexと2つの条件変数empty_queue(キューが空の場合はコンシューマをサスペンドする)とfull_queue(キューがいっぱいの場合はプロデューサをサスペンドする)で行われます。問題は、両方のスレッドがMAX_QUEUEの要素が生成/消費されたときに停止し、デッドロック状態になることです。私はすべてが正しいと思う、私は間違って何をしているのか分からない。

プロデューサー:

void* producer(void* args) { 
    unsigned seed = time(NULL); 
    int random; 
    queue *coda = (queue *) args; 

    while(1) { 
     Pthread_mutex_lock(&queue_lock); 
     while(coda->head == MAX_QUEUE-1) { // Full Queue 
      printf("Suspending producer\n"); 
      fflush(stdout); 
      Pthread_cond_wait(&full_queue, &queue_lock); 
     } 

     random = rand_r(&seed) % 21; 
     enqueue(coda, random); 

     Pthread_cond_signal(&empty_queue); 
     Pthread_mutex_unlock(&queue_lock); 

     sleep(1); 
    } 

    return NULL; 
} 

消費者:

void* consumer(void* args) { 
    queue *coda = (queue *) args; 
    int elem; 

    while(1) { 
     Pthread_mutex_lock(&queue_lock); 
     while(coda->head == coda->tail) { // Empty Queue 
      printf("Suspending Consumer\n"); 
      fflush(stdout); 
      Pthread_cond_wait(&empty_queue, &queue_lock); 
     } 

     elem = dequeue(coda); 
     printf("Found %i\n",elem); 

     Pthread_cond_signal(&full_queue); 
     Pthread_mutex_unlock(&queue_lock); 
    } 

    return NULL; 
} 

エンキュー/デキューは

static void enqueue(queue *q, int elem) { 
    q->q[(q->tail)] = elem; 
    (q->tail)++; 
    if(q->tail == MAX_QUEUE) 
     q->tail = 0; 
} 

static int dequeue(queue *q) { 
    int elem = q->q[(q->head)]; 
    (q->head)++; 
    if(q->head == MAX_QUEUE) 
     q->head = 0; 
    return elem; 
} 

Pthread_ *ルーチン標準pthread_ *ライブラリ関数への単なるラッパー関数です。 (= 10 MAX_QUEUE付き) 出力:

Suspending Consumer 
Found 16 
Suspending Consumer 
Found 7 
Suspending Consumer 
Found 5 
Suspending Consumer 
Found 6 
Suspending Consumer 
Found 17 
Suspending Consumer 
Found 1 
Suspending Consumer 
Found 12 
Suspending Consumer 
Found 14 
Suspending Consumer 
Found 11 
Suspending Consumer 
Suspending producer 

答えて

0
coda->head == MAX_QUEUE-1 

これは、キューが満杯であるかどうかをチェックしません。キューの状態を表す2つの変数、headおよびtailがあります。

coda->head == coda->tail 

これは、キューが空であることを適切にチェックします。両方の変数がチェックでどのように使用されているかに注意してください。

+0

'(coda-> tail + 1)%MAX_QUEUE == coda-> head'を使用して解決しました。提案していただきありがとうございます。 –

関連する問題