Jernej Bevk
Jernej Bevk

Reputation: 25

multiple threads in Linux C

I am trying tu calculate value of PI. I have multiple threads that are calculating PI. If difference between my PI and original PI is smaller than 0.0001, I want to send signal to other thread and finish threads. The other thread (that received signal) prints out the value of my PI.

I wrote program, but sometimes it works correctly, sometimes not :) Can anyone help me?

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#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);
}

Upvotes: 2

Views: 433

Answers (1)

hyde
hyde

Reputation: 62908

You are using variable diff from multiple threads without it being protected by mutex always.

Also, as said in man page of rand():

The function rand() is not reentrant or thread-safe, since it uses hidden state that is modified on each call


At a 2nd glance, your problem is, diff may change after you test it in loop, and before you lock the mutex. You need to rethink your locking logic a bit to avoid this race condition.

Upvotes: 2

Related Questions