Comportement de thread du tuto Developpez.com
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
Code:
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;
} |
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:
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;
} |
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.
Pourquoi ce comportement s'intalle au fil du temps ?
De plus, quand on retire la ligne de la fonction client
Code:
psleep (get_random (3));
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.