Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not sure if I need a mutex or not

I'm new to concurrent programming so be nice. I have a basic sequential program (which is for homework) and I'm attempting to turn it into a multithreaded program. I'm not sure if I need a lock for my second shared variable. The threads should modify my variable but never read them. The only time count should be read is after the loop which spawns all of my threads has finished distributing keys.

#define ARRAYSIZE 50000

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

void binary_search(int *array, int key, int min, int max); 

int count = 0; // count of intersections
int l_array[ARRAYSIZE * 2]; //array to check for intersection

int main(void)
{
    int r_array[ARRAYSIZE]; //array of keys
    int ix = 0;

    struct timeval start, stop;
    double elapsed;

    for(ix = 0; ix < ARRAYSIZE; ix++)
    {
        r_array[ix] = ix;
    }
    for(ix = 0; ix < ARRAYSIZE * 2; ix++)
    {
        l_array[ix] = ix + 500;
    }

    gettimeofday(&start, NULL);

    for(ix = 0; ix < ARRAYSIZE; ix++)
    {
        //this is where I will spawn off separate threads
        binary_search(l_array, r_array[ix], 0, ARRAYSIZE * 2);
    }

    //wait for all threads to finish computation, then proceed.

    fprintf(stderr, "%d\n", count);

    gettimeofday(&stop, NULL);
    elapsed = ((stop.tv_sec - start.tv_sec) * 1000000+(stop.tv_usec-start.tv_usec))/1000000.0;
    printf("time taken is %f seconds\n", elapsed);
    return 0;
}

void binary_search(int *array, int key, int min, int max)
{
    int mid = 0;
    if (max < min) return;
    else
    {
      mid = (min + max) / 2;
      if (array[mid] > key) return binary_search(array, key, min, mid - 1);
      else if (array[mid] < key) return binary_search(array, key, mid + 1, max);
      else 
      {
          //this is where I'm not sure if I need a lock or not
          count++;
          return;
      }
    }
}
like image 972
AlexLordThorsen Avatar asked Dec 07 '22 11:12

AlexLordThorsen


2 Answers

As you suspect, count++; requires synchronization. This is actually not something you should try to "get away with" not doing. Sooner or later a second thread will read count after the first thread reads it but before it increments it. Then you will miss a count. It is impossible to predict how often it will happen. It could happen once in a blue moon or thousands of times a second.

like image 102
ThomasMcLeod Avatar answered Dec 09 '22 01:12

ThomasMcLeod


Actually, the code as you've written it does both read and modify the variable. If you were to look at the machine code that gets generated for a line like

count++

you'd see that it consists of something like

fetch count into register
increment register
store count

So yes, you should use a mutex there. (And even if you could get away without doing so, why not take the chance to practice?)

like image 37
David Z Avatar answered Dec 09 '22 01:12

David Z