When i try running this code i get an error 'Floating Point Exception'. I dont know why this is happening.

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <pthread.h>


  long long int number_of_tosses, number_of_threads, number_in_circle = 0;
 
  pthread_mutex_t mutex;
 

void *mc(void* rank)

{

    double x, y, distance_squared, pi_estimate;  

    int toss;

    long long int n;

    n = number_of_tosses/number_of_threads;

    srandom((unsigned)time(NULL));

 for ( toss=0 ; toss< n ; toss++) {
   pthread_mutex_lock(&mutex);
      x =  2*(rand()/((double)RAND_MAX)) - 1.0;

      y =  2*(random()/((double)RAND_MAX)) - 1.0;

    distance_squared = x * x + y * y;

    if(distance_squared <= 1)number_in_circle++;
pthread_mutex_unlock(&mutex);
  }
  
//  pi_estimate = 4 * number_in_circle/((double) number_of_tosses);
  /*
   if(rank == 0) {
 
    printf("Thread %d: pi estimate = %f\n", (int)rank, pi_estimate);

} */

return NULL;

}
 

int main(){

  long thread;
    
  double pi_estimate;

  int number_of_threads;

  pthread_t* thread_handles;
  
  printf("Enter number of tosses: \n");
  
  scanf("%lld", &number_of_tosses);

  printf("Enter number of threads: ");
  
  scanf("%d", &number_of_threads);

  thread_handles = malloc (number_of_threads * sizeof(pthread_t));

  pthread_mutex_init(&mutex, NULL);
  
 for(thread = 0; thread < number_of_threads; thread++)

  pthread_create(&thread_handles[thread], NULL, mc, (void*) thread);

  // printf("Main thread \n");

 for(thread = 0; thread < number_of_threads; thread++)

  pthread_join(thread_handles[thread], NULL);

  pthread_mutex_destroy(&mutex);

  free(thread_handles);

if(thread == 0) {

  pi_estimate = 4 * number_in_circle/((double) number_of_tosses);
 
  printf("Pi estimate: %f\n", pi_estimate);

}
return 0;

}

The main issue was that you defined a variable in main() called number_of_threads and a global variable number_of_threads. When you read in the value of number_of_threads it was to the local variable and not the global. So, when the threads read the value of the global number_of_threads it was ZERO.
Also, you were using rand and random. I don't know if that is what you wanted. I changed them both to rand_r because rand is not thread-safe.

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

long long int number_of_tosses, number_of_threads, number_in_circle = 0;
pthread_mutex_t mutex;
 
void *mc(void* rank) {
    double x, y, distance_squared, pi_estimate;  
    unsigned int seedp;
    int toss;
    long long int n;
    n = number_of_tosses/number_of_threads;
    srandom((unsigned)time(NULL));
    for ( toss=0 ; toss< n ; toss++) {
       pthread_mutex_lock(&mutex);
       x =  2*(rand_r(&seedp)/((double)RAND_MAX)) - 1.0;
       y =  2*(rand_r(&seedp)/((double)RAND_MAX)) - 1.0;
       distance_squared = x * x + y * y;
       if(distance_squared <= 1.0)
          number_in_circle++;
       pthread_mutex_unlock(&mutex);
  }
  
//  pi_estimate = 4 * number_in_circle/((double) number_of_tosses);
  /*
   if(rank == 0) {
 
    printf("Thread %d: pi estimate = %f\n", (int)rank, pi_estimate);

} */

  pthread_exit(0);

}

int main(){
  long thread;
  double pi_estimate;
  // int number_of_threads;   <--------------- ERROR!!   <-----------
  pthread_t* thread_handles;
  printf("Enter number of tosses: \n");
  scanf("%lld", &number_of_tosses);
  printf("Enter number of threads: ");
  scanf("%lld", &number_of_threads);   // <---- Changed to %lld  <------------
  thread_handles = (pthread_t*)malloc (number_of_threads * sizeof(pthread_t));
  pthread_mutex_init(&mutex, NULL);
  for(thread = 0; thread < number_of_threads; thread++)
      pthread_create(&thread_handles[thread], NULL, mc, (void*) thread);

  // printf("Main thread \n");
  for(thread = 0; thread < number_of_threads; thread++)
      pthread_join(thread_handles[thread], NULL);

  pthread_mutex_destroy(&mutex);
  free(thread_handles);
  // if(thread == 0) {
  pi_estimate = 4 * number_in_circle/((double) number_of_tosses);
  printf("Pi estimate: %f\n", pi_estimate);
  //}
  return 0;
}

Output:

$ ./a.out
Enter number of tosses: 
10000000
Enter number of threads: 10
Pi estimate: 3.140172
$

You might want to try http://linux.die.net/man/3/random_r to see if it is better.

Edited 4 Years Ago by histrungalot: n/a

The main issue was that you defined a variable in main() called number_of_threads and a global variable number_of_threads. When you read in the value of number_of_threads it was to the local variable and not the global. So, when the threads read the value of the global number_of_threads it was ZERO.
Also, you were using rand and random. I don't know if that is what you wanted. I changed them both to rand_r because rand is not thread-safe.

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

long long int number_of_tosses, number_of_threads, number_in_circle = 0;
pthread_mutex_t mutex;
 
void *mc(void* rank) {
    double x, y, distance_squared, pi_estimate;  
    unsigned int seedp;
    int toss;
    long long int n;
    n = number_of_tosses/number_of_threads;
    srandom((unsigned)time(NULL));
    for ( toss=0 ; toss< n ; toss++) {
       pthread_mutex_lock(&mutex);
       x =  2*(rand_r(&seedp)/((double)RAND_MAX)) - 1.0;
       y =  2*(rand_r(&seedp)/((double)RAND_MAX)) - 1.0;
       distance_squared = x * x + y * y;
       if(distance_squared <= 1.0)
          number_in_circle++;
       pthread_mutex_unlock(&mutex);
  }
  
//  pi_estimate = 4 * number_in_circle/((double) number_of_tosses);
  /*
   if(rank == 0) {
 
    printf("Thread %d: pi estimate = %f\n", (int)rank, pi_estimate);

} */

  pthread_exit(0);

}

int main(){
  long thread;
  double pi_estimate;
  // int number_of_threads;   <--------------- ERROR!!   <-----------
  pthread_t* thread_handles;
  printf("Enter number of tosses: \n");
  scanf("%lld", &number_of_tosses);
  printf("Enter number of threads: ");
  scanf("%lld", &number_of_threads);   // <---- Changed to %lld  <------------
  thread_handles = (pthread_t*)malloc (number_of_threads * sizeof(pthread_t));
  pthread_mutex_init(&mutex, NULL);
  for(thread = 0; thread < number_of_threads; thread++)
      pthread_create(&thread_handles[thread], NULL, mc, (void*) thread);

  // printf("Main thread \n");
  for(thread = 0; thread < number_of_threads; thread++)
      pthread_join(thread_handles[thread], NULL);

  pthread_mutex_destroy(&mutex);
  free(thread_handles);
  // if(thread == 0) {
  pi_estimate = 4 * number_in_circle/((double) number_of_tosses);
  printf("Pi estimate: %f\n", pi_estimate);
  //}
  return 0;
}

Output:

$ ./a.out
Enter number of tosses: 
10000000
Enter number of threads: 10
Pi estimate: 3.140172
$

You might want to try http://linux.die.net/man/3/random_r to see if it is better.

Thanks for your help!

This article has been dead for over six months. Start a new discussion instead.