Bonjour,
Dans le cadre d’un cours de programmation, j’essaye de tester les différentes possibilités de synchronisation entre threads possibles. L’exercice est un peu idiot: faire deux threads, un qui récupère les caractères entré, l’autre qui les compte (bref, producteur/consommateur). J’ai commencé par implémenter ça avec des mutex, et évidement, ça fonctionne. Puis on m’a demandé de tester avec pthread_cond_t
. Et là, j’ai compris le principe (je crois), mais ça ne fonctionne pas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <stdbool.h> #include <pthread.h> int n = 0; int total = 0; pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; bool producer_done = false, running = true; void* read_chars(void* arg) { char c = 0; while(running) { pthread_mutex_lock(&mut); c = fgetc(stdin); if (c == '\n') { producer_done = true; pthread_cond_broadcast(&cond); } else if (c == '$') { // faut bien que j'arrête le programme à un moment running = false; pthread_cond_broadcast(&cond); } else n += 1; pthread_mutex_unlock(&mut); } pthread_exit(NULL); } void* count_chars(void* arg) { while(running) { pthread_mutex_lock(&mut); while(!producer_done) { pthread_cond_wait(&cond, &mut); } producer_done = false; total += n; n = 0; printf("counted: %d\n", total); pthread_mutex_unlock(&mut); } pthread_exit(NULL); } int main() { pthread_t threads[2]; int i, res; res = pthread_create(&threads[1], NULL, count_chars, NULL); if (res != 0) perror("pthread_create"); res = pthread_create(&threads[0], NULL, read_chars, NULL); if (res != 0) perror("pthread_create"); for (i=0; i < 2; i++) { res = pthread_join(threads[i], NULL); if (res != 0) perror("pthread_join"); } pthread_cond_destroy(&cond); pthread_mutex_destroy(&mut); exit(EXIT_SUCCESS); } |
Normalement, pthread_cond_wait(&cond, &mut)
devrait s’endormir passer la main à l’autre thread (et en effet). Mais ensuite, pthread_cond_broadcast(&cond)
devrait réveiller le thread en attente et le faire avancer. Et là … Non. Rien n’y fait, je n’ai jamais mon compte de caractère qui s’affiche, à part à la fin (quand je met un $
, donc). Et quand je met un printf
avant et après le broadcast, je vois qu’il a broadcasté, mais l’autre thread ne se réveille pas pour autant.
J’ai raté un truc ?
D’avance merci si vous savez m’expliquer ce que j’ai pas compris