algolejos
algolejos

Reputation: 139

How to make thread safe program?

On a 64-bit architecture pc, the next program should return the result 1.350948. But it is not thread safe and every time I run it gives (obviously) a different result.

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

const unsigned int ndiv = 1000;
double res = 0;

struct xval{
  double x;
};

// Integrate exp(x^2 + y^2) over the unit circle on the
// first quadrant.
void* sum_function(void*);
void* sum_function(void* args){
  unsigned int j;
  double y = 0;
  double localres = 0;
  double x = ((struct xval*)args)->x;

  for(j = 0; (x*x)+(y*y) < 1; y = (++j)*(1/(double)ndiv)){
    localres += exp((x*x)+(y*y));
  }

  // Globla variable:
  res += (localres/(double)(ndiv*ndiv));
  // This is not thread safe!
  // mutex? futex? lock? semaphore? other?
}

int main(void){  
  unsigned int i;
  double x = 0;

  pthread_t thr[ndiv];
  struct xval* xvarray;

  if((xvarray = calloc(ndiv, sizeof(struct xval))) == NULL){
    exit(EXIT_FAILURE);
  }

  for(i = 0; x < 1; x = (++i)*(1/(double)ndiv)){
    xvarray[i].x = x;
    pthread_create(&thr[i], NULL, &sum_function, &xvarray[i]);
    // Should check return value.
  }

  for(i = 0; i < ndiv; i++){
    pthread_join(thr[i], NULL);
    // If
    // pthread_join(thr[i], &retval);
    // res += *((double*)retval) <-?
    // there would be no problem.
  }

  printf("The integral of exp(x^2 + y^2) over the unit circle on\n\
    the first quadrant is: %f\n", res);

  return 0;
}

How can it be thread safe?

NOTE: I know that 1000 threads is not a good way to solve this problem, but I really really want to know how to write thread-safe c programs.

Compile the above program with

gcc ./integral0.c -lpthread -lm -o integral

Upvotes: 0

Views: 107

Answers (2)

user3386109
user3386109

Reputation: 34829

The question (in a comment in the code):

// mutex? futex? lock? semaphore? other?

Answer: mutex.

See pthread_mutex_init, pthread_mutex_lock, and pthread_mutex_unlock.

Upvotes: 1

jigglypuff
jigglypuff

Reputation: 527

pthread_mutex_lock(&my_mutex);

// code to make thread safe

pthread_mutex_unlock(&my_mutex);

Declare my_mutex either as a global variable like pthread_mutex_t my_mutex;. Or initialize in code using pthread_mutex_t my_mutex; pthread_mutex_init(&my_mutex, NULL);. Also don't forget to include #include <pthread.h> and link your program with -lpthread when compiling.

Upvotes: 3

Related Questions