Bonjour à tous,
J'ai étudié le tutoriel sur les thread en C (https://franckh.developpez.com/tutor...osix/pthreads/) et j'ai remarqué des comportements curieux.
Quand je lance le programme sur le dernier exemple (qui limite la charge CPU), avec les threads fn_clients
la sortie affichée montre des clients 0, 1, 2, 3, 4 qui s'enchainent aléatoirement pour prendre dans le thread stock, ce qui me semble attendu.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 /* Fonction pour les threads des clients. */ static void * fn_clients (void * p_data) { int nb = (int) p_data; while (1) { int val = get_random (6); psleep (get_random (3)); /* Debut de la zone protegee. */ pthread_mutex_lock (& store.mutex_stock); if (val > store.stock) { pthread_cond_signal (& store.cond_stock); pthread_cond_wait (& store.cond_clients, & store.mutex_stock); } store.stock = store.stock - val; printf ( "Client %d prend %d du stock, reste %d en stock !\n", nb, val, store.stock ); pthread_mutex_unlock (& store.mutex_stock); /* Fin de la zone protegee. */ } return NULL; }
Puis passé un certain délai, l'enchainement aléatoire ne se passe plus, il y a juste un thread client X qui pioche dans le stocke jusqu'à épuisement, puis c'est le tour d'une autre thread client Y d'aller piocher.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 /* Fonction pour le thread du magasin. */ static void * fn_store (void * p_data) { while (1) { /* Debut de la zone protegee. */ pthread_mutex_lock (& store.mutex_stock); pthread_cond_wait (& store.cond_stock, & store.mutex_stock); store.stock = INITIAL_STOCK; printf ("Remplissage du stock de %d articles !\n", store.stock); pthread_cond_signal (& store.cond_clients); pthread_mutex_unlock (& store.mutex_stock); /* Fin de la zone protegee. */ } return NULL; }
Pourquoi ce comportement s'intalle au fil du temps ?
De plus, quand on retire la ligne de la fonction client
le code finit par se bloquer tout seul sans cracher (ce qui me fait penser à un Dead Lock évoqué dans le tuto) en ayant justement l'appel du client X qui pioche jusqu'à 0 stock puis c'est le client Y.
Code : Sélectionner tout - Visualiser dans une fenêtre à part psleep (get_random (3));
Partager