I am writting a program which computes the value of pi using the bailey-borwein-plouffe formula.My problem is i keep getting different results whenever i run this code using the mutex.I am not sure if the mutex lock in the pie function definition should be used for just one resource pi .
enter code here
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#define NUM_THREADS 1000
void *pie_function(void * p);//returns the value of pie
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; //creates a mutex variable
double pi=0,p16=1;
main()
{
pthread_t threads[NUM_THREADS]; //creates the number of threads using NUM_THREADS
int iret1; //used to ensure that threads are created properly
//pthread_create(thread,attr,start_routine,arg)
int i;
pthread_mutex_init(&mutex1, NULL);
for(i=0;i<NUM_THREADS;i++){
iret1= pthread_create(&threads[i],NULL,pie_function,(void *) i);
if(iret1){
printf("ERROR; return code from pthread_create() is %d\n", iret1);
exit(-1);
}
}
for(i=0;i<NUM_THREADS;i++){
iret1=pthread_join(threads[i],NULL);
if(iret1){
printf("ERROR; return code from pthread_create() is %d\n", iret1);
exit(-1);
}
}
pthread_mutex_destroy(&mutex1);
printf("Main: program completed. Exiting.\n");
printf("The value of pi is : %f\n",pi);
exit(0);
}
void *pie_function(void *s){
int rc;
int k=(int) s;
pthread_mutex_lock( &mutex1 ); //locks the share variable pi and p16
pi += 1.0/p16 * (4.0/(8*k + 1) - 2.0/(8*k + 4) - 1.0/(8*k + 5) - 1.0/(8*k+6));
p16 *=16;
rc=pthread_mutex_unlock( &mutex1 );
if(rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
You would be better off ditching threads totally in this case.
Threading is handy when a group of threads can execute mostly in their own little world without affecting each other (occasional resource contention is okay).
However, since your threads are very short-lived and pretty well lock the mutex for their entire lifetime, you are getting no advantage from threading. All you’re doing is adding extra overhead for little or no benefit.
This particular task would be better handled a a series of sequential steps.
However, if you feel you must do this thing, you can fix the problem by looking at the following formula:
Obviously, what gets added to
pidepends on bothkandp16. Now yourp16is well-controlled (within the mutex) but yourkis not since it’s passed in as a parameter.The problem you have is that, even though you may start the thread with
k == 7before the one withk == 8, there’s no guarantee that the former will get the mutex first. If the latter gets the mutex first, yourkandp16will not have “compatible” values. Such are the vagaries of threading.You can fix this by putting
kunder the control of the mutex.In other words, don’t pass it as a parameter, rather do the same thing as you do with
p16. Initialise them all with:Then have your thread function contain:
This way, the values of
kandp16are kept in step regardless of the order of thread execution.However, I still maintain that threads are a bad idea in this case.