plusieurs threads dans Linux C

J’essaie de calculer la valeur de PI. J’ai plusieurs threads qui calculent PI. Si la différence entre mon PI et le PI original est inférieure à 0,0001, je souhaite envoyer un signal à d’autres threads et terminer les threads. L’autre thread (le signal reçu) imprime la valeur de mon PI.

J’ai écrit le programme, mais parfois cela fonctionne correctement, parfois pas 🙂 Quelqu’un peut-il m’aider?

#include  #include  #include  #include  #define N_THR 3 double ns=0; double zs=0; double moj_pi=0; int count=0; double diff=100; pthread_mutex_t count_mutex; pthread_cond_t count_cv; void *watch_count(void *t){ pthread_mutex_lock(&count_mutex); while (diff>=0.0001) { pthread_cond_wait(&count_cv, &count_mutex); printf("Calculated PI: %f.\n", moj_pi); } pthread_mutex_unlock(&count_mutex); pthread_exit(NULL); } void *inc_count(void *t){ while(diff>=0.0001){ double x = ((double) rand()) / RAND_MAX; double y = ((double) rand()) / RAND_MAX; pthread_mutex_lock(&count_mutex); ns++; if (x*x + y*y <=1){ zs++; } moj_pi=4* zs / ns; printf("PI: %f\n",moj_pi); diff=M_PI - moj_pi; if (diff<0) diff=0-diff; printf("Difference: %f\n",diff); if (diff <0.0001){ pthread_cond_signal(&count_cv); } pthread_mutex_unlock(&count_mutex); } pthread_exit(NULL); } int main(){ int i; pthread_t id[N_THR]; pthread_attr_t attr; pthread_mutex_init(&count_mutex, NULL); pthread_cond_init(&count_cv, NULL); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_create(&id[0], &attr, watch_count, (void *)1); for (i=1;i<N_THR;i++) pthread_create(&id[i], &attr, inc_count, (void *)(i+1)); for (i=0;i<N_THR;i++) pthread_join(id[i], NULL); pthread_attr_destroy(&attr); pthread_mutex_destroy(&count_mutex); pthread_cond_destroy(&count_cv); pthread_exit(NULL); } 

Vous utilisez la variable diff partir de plusieurs threads sans la protéger toujours par mutex.

Aussi, comme dit dans la page de manuel de rand() :

La fonction rand () n’est pas réentrante ou thread-safe, car elle utilise un état caché modifié à chaque appel


Au deuxième coup d’œil, votre problème est que diff peut changer après l’avoir testé en boucle et avant de verrouiller le mutex. Vous devez repenser votre logique de locking pour éviter cette condition de course.