Bonjour!
Je suis (toujours) en train de coder la simulation d'un bus CAN en C, et j'en suis à la phase de débuggage. Tous les problèmes que j'ai pu rencontrer ont été résolus, sauf un que je ne comprend vraiment pas.
J'utilise plusieurs threads pour ce projet, et en particulier les deux threads suivants :
Ce thread me sert d'horloge, et est utilisé pour synchroniser tous les autres threads entre eux. Il écrit TIC dans la console tous les 10 ms.
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 while(1) { usleep(905); // sleep 0.905 ms time_since_beginning=time_since_beginning+1; // time printf(" TIC "); if(time_since_beginning%10==0) { pthread_mutex_lock (&mutex3); pthread_cond_broadcast (&t_to_0ms); pthread_mutex_unlock (&mutex3); } else if(time_since_beginning%10==3) { pthread_mutex_lock (&mutex4); pthread_cond_broadcast (&t_to_3ms); pthread_mutex_unlock (&mutex4); } else if(time_since_beginning%10==5) { pthread_mutex_lock (&mutex5); pthread_cond_broadcast (&t_to_5ms); pthread_mutex_unlock (&mutex5); } else if(time_since_beginning%10==6) { pthread_mutex_lock (&mutex6); pthread_cond_broadcast (&t_to_6ms); pthread_mutex_unlock (&mutex6); } else if(time_since_beginning%10==7) { pthread_mutex_lock (&mutex7); pthread_cond_broadcast (&t_to_7ms); pthread_mutex_unlock (&mutex7); } else if(time_since_beginning%10==9) { pthread_mutex_lock (&mutex8); pthread_cond_broadcast (&t_to_9ms); pthread_mutex_unlock (&mutex8); } } } }
Ce morceau de thread est ce qui fait bugger mon programme, de manière totalement aléatoire. Par exemple, le programme peut tourner pendant longtemps avant de bugger (genre 10 minutes, avec un tour de boucle fait toutes les 10 ms), ou le faire dans les 1ères secondes.
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 while(1) { counter1++; printf("a"); pthread_mutex_lock(&mutex3); pthread_cond_wait (&t_to_0ms, &mutex3); pthread_mutex_unlock(&mutex3); printf("b"); //instructions rapides, du genre if(something), printf(something) printf("e"); //pthread_mutex_lock(&mutex4); //pthread_cond_wait (&t_to_3ms, &mutex4); // on attend qu'un calcul soit fait dans un autre thread //pthread_mutex_unlock(&mutex4); printf("f"); pthread_mutex_lock(&mutex5); pthread_cond_wait (&t_to_5ms, &mutex5); // le calcul est fini dans l'autre thread pthread_mutex_unlock(&mutex5); printf("g"); //instructions rapides, du genre if(something), printf(something) printf("h"); }
Tous les threads sont synchronisés entre eux de façon à faire des boucles qui se répètent toutes les 10 ms. Le problème est que ce thread en particulier se désynchronise parfois des autres, ce qui provoque une erreur dans mes calculs et fait s'arrêter mon programme.
Il y a des problèmes qui apparaissent à deux endroits : au niveau du printf("f") et du printf("a").
Je voudrais que le programme avance 'logiquement', et que toutes les 10 ms j'affiche
C'est effectivement ce qui se passe presque tout le temps, mais parfois à la place j'ai... TIC abcdefgh TIC abcdefgh TIC ...
Le thread semble 'louper' le broadcast de t_to_5ms, et ne le récupère qu'au tour de boucle suivant. Il se passe parfois la même chose au niveau de printf("a"), ou le thread reste bloqué pour un tour de boucle en attente du t_to_0ms.... TIC abcdefgh TIC abcdef TIC gh TIC abcdefgh TIC ...
Le plus étrange c'est que l'erreur n'est pas systèmatique et peut arriver à n'importe quel moment, au premier tour de boucle comme au 10 000 ème. Mes autres threads utilisent les mêmes pthread_cond_wait et marchent correctement.
Si vous avez une idée sur pourquoi cela fait ça, ou encore mieux, une solution au problème, je serais très heureux!
Partager