Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using mutex for pthread results in random answer

Tags:

c

mutex

pthreads

I have written a simple pthread code which

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

#define ITERATIONS 500

// A shared mutex
pthread_mutex_t mutex;
int target;

void* opponent(void *arg)
{
  int i;
  printf("opp, before for target=%d\n", target);
  pthread_mutex_lock(&mutex);
  for(i = 0; i < ITERATIONS; ++i)
  {
    target++;
  }
  pthread_mutex_unlock(&mutex);
  printf("opp, after for target=%d\n", target);

  return NULL;
}

int main(int argc, char **argv)
{
  pthread_t other;

  target = 5;

  // Initialize the mutex
  if(pthread_mutex_init(&mutex, NULL))
  {
    printf("Unable to initialize a mutex\n");
    return -1;
  }

  if(pthread_create(&other, NULL, &opponent, NULL))
  {
    printf("Unable to spawn thread\n");
    return -1;
  }

  int i;
  printf("main, before for target=%d\n", target);
  pthread_mutex_lock(&mutex);
  for(i = 0; i < ITERATIONS; ++i)
  {
    target--;
  }
  pthread_mutex_unlock(&mutex);
  printf("main, after for target=%d\n", target);

  if(pthread_join(other, NULL))
  {
    printf("Could not join thread\n");
    return -1;
  }

  // Clean up the mutex
  pthread_mutex_destroy(&mutex);

  printf("Result: %d\n", target);

  return 0;
}

Then I compile with this command

gcc -pedantic -Wall -o theaded_program pth.c -lpthread

However, every time I run the program, I get different results!!

 $ ./theaded_program
 main, before for target=5
 main, after for target=-495
 opp, before for target=5
 opp, after for target=5
 Result: 5

 $ ./theaded_program
 main, before for target=5
 opp, before for target=5
 opp, after for target=5
 main, after for target=-495
 Result: 5
like image 342
mahmood Avatar asked Jan 25 '26 00:01

mahmood


1 Answers

The printf() statements are not executed when the mutex is locked and they are accessing target:

printf("opp, before for target=%d\n", target);
pthread_mutex_lock(&mutex);

This means one thread is potentially changing the value of target while another thread is attempting to read it (in the printf()). Move the printf() statements to be executed when the mutex is locked:

pthread_mutex_lock(&mutex);
printf("opp, before for target=%d\n", target);
/* snip */
printf("opp, after for target=%d\n", target);
pthread_mutex_unlock(&mutex);

This will prevent target being read by one thread and modified by another concurrently. However, there is no guarantee which thread will first acquire the mutex.

like image 154
hmjd Avatar answered Jan 26 '26 14:01

hmjd



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!