0

I am trying to make race condition and fix it with mutex lock. My code is working correct which is no race condition. Should not it make race condition?

#define MAX_RESOURCES 10

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

int available_resources = 10;
void* decrease_count(void count);
void increase_count(void *count);

pthread_t thread1;
pthread_t thread2;

int main () {
    int decrease = 8;
    int increase = 3;

    pthread_create(&thread1, NULL, decrease_count, (void*) &decrease);
    pthread_create(&thread2, NULL, increase_count, (void*) &increase);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    printf("amount of resource: %d",available_resources);

    return 0;
}

void* decrease_count(void *count){
    available_resources -= *((int *)count);

    return NULL;
}

void* increase_count(void *count){
    if(available_resources + *((int *)count) <=  MAX_RESOURCES) {
         available_resources += *((int *)count);
         return 0;
     }
        
    return NULL;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
ken d
  • 1
  • 1

1 Answers1

0

Well, here, you are declaring in your thread function that you are going to be passed a reference to the increment/decrement value, so you can control how many counts each thread does when it runs.

The idea is to create a mutex in main, and use it in both threads to lock the resource, before doing the increment/decrement.

#define MAX_RESOURCES 10

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

int available_resources = 10;
void* decrease_count(void *count);
void* increase_count(void *count);

pthread_t       thread1;
pthread_t       thread2;
pthread_mutex_t the_mutex;

int main () {
    int decrease = 8;
    int increase = 3;

    /* create the mutex before any of the threads has access to it */
    int res = pthread_mutex_init(&the_mutex, NULL);
    if (res < 0) {
        fprintf(stderr, "pthread_create_mutex: %s\n",
            strerror(errno));
    }

    pthread_create(&thread1, NULL, decrease_count, &decrease);
    pthread_create(&thread2, NULL, increase_count, &increase);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    printf("amount of resource: %d\n",available_resources);

    return 0;
}

void* decrease_count(void *_count){
    int count = *(int *)_count;

    int res = pthread_mutex_lock(&the_mutex);
    if (res < 0) {
        fprintf(stderr, "%s: mutex lock: %s\n",
                __func__,
                strerror(errno));
    }
    available_resources -= count;
    res = pthread_mutex_unlock(&the_mutex);
    if (res < 0) {
        fprintf(stderr, "%s: mutex unlock: %s\n",
                __func__,
                strerror(errno));
    }

    return NULL;
}

void* increase_count(void *_count){
    int count = *(int *)_count;
    int res = pthread_mutex_lock(&the_mutex);
    int overflow = 0;
    if (res < 0) {
        fprintf(stderr,
                "%s: mutex lock: %s\n",
                __func__,
                strerror(errno));
    }
    if(available_resources + count <=  MAX_RESOURCES) {
         overflow = 1;
         available_resources += count;
    }
    res = pthread_mutex_unlock(&the_mutex);
    if (res < 0) {
        fprintf(stderr, "%s: mutex unlock: %s\n",
                __func__,
                strerror(errno));
    }
    if (overflow) {
        printf("got over the top(%d resources)\n",
                MAX_RESOURCES);
    }
    return NULL;        
}
Luis Colorado
  • 10,974
  • 1
  • 16
  • 31