2010-11-03 47 views
0

j'ai écrit le code suivant:pthreads de blocage producteur-consommateur

void *produce(void* arg) 
{ 
buffer* buff = (buffer *) arg; 
while (1) 
{ 
    pthread_mutex_lock(&mutex); 
    if (elements_produced == JOB_SIZE) 
    { 
    pthread_mutex_unlock(&mutex); 
    pthread_exit(NULL); 
    } 
    elements_produced++; 

    while (buff->in_buff == CAPACITY) 
    { 
    pthread_cond_wait(&cond_empty, &mutex); 
    } 

    // produce 
    buff->buffer[buff->tail] = rand(); 
    sum_produced += buff->buffer[buff->tail]; 
    printf(">produced %d\n", buff->buffer[buff->tail]); 

    buff->tail = (buff->tail + 1) % CAPACITY; 
    buff->in_buff++; 
    pthread_cond_signal(&cond_empty); 
    pthread_mutex_unlock(&mutex); 
} 
pthread_exit(NULL); 
} 

void *consume(void* arg) 
{ 
int rc; 
buffer* buff = (buffer *) arg; 
while (1) 
{ 
    rc = pthread_mutex_lock(&mutex); 

    if (elements_consumed == JOB_SIZE) 
    { 
    pthread_mutex_unlock(&mutex); 
    pthread_exit(NULL); 
    return 0; 
    } 
    elements_consumed++; 

    while (buff->in_buff == 0) 
    { 
    rc = pthread_cond_wait(&cond_empty, &mutex); 
    } 

    // consume 
    printf("<consumed %d\n", buff->buffer[buff->head]); 
    sum_consumed += buff->buffer[buff->head]; 
    buff->head = (buff->head + 1) % CAPACITY; 
    buff->in_buff--; 
    pthread_cond_signal(&cond_full); 
    pthread_mutex_unlock(&mutex); 
} 
pthread_exit(NULL); 
return 0; 
} 

Toutes les variables sont correctement initialisés. La tâche consiste à produire des éléments JOB_SIZE et à les consommer. De temps en temps, il se coince dans le verrou mort. Je suis assez nouveau sur les threads posix, donc il me manque probablement quelque chose de très évident (les producteurs/consommateurs ont plusieurs fois java/C#/python mais maintenant je suis vraiment bloqué). Je sais que c'est beaucoup plus facile de le faire avec des sémaphores, mais je dois le faire de cette façon.

Des suggestions?

+0

Combien de condars sont impliqués? Le producteur devrait-il attendre 'cond_full' plutôt que 'cond_empty'? –

Répondre

3

Vous avez utilisé cond_empty des deux côtés pour l'attente. Vous signalez (mais n'attendez jamais) cond_full.

+0

Attente de 'cond_empty' dans les deux cas devrait fonctionner, mais vous devez vous assurer que vous le signal dans les deux cas aussi. –

+0

Je me sens un peu gêné après cela. Je ne sais pas comment je n'avais pas vu ça. Tnx. – Klark

+0

@Anthony Williams: C'est ce que je pensais qu'il faisait au début, donc je n'ai presque pas attrapé l'autre condition. –