I have this very simple multi-threaded program where I am reading a bunch of numbers and eventually adding them to a global sum
. I am using the local_sum
variable in each thread which I then add to the global sum
. The code is given at the end.
The question is - Do I need to lock this line of code in the thread_runner
function?
sum += local_sum;
I am pretty sure that I do need to lock this however the program always gives the right result anyway. If I do need locks, how do I prove that this implementation is wrong?
Note: I am only interested in mutex locks as the synchronization primitive here. Also please ignore that I have not checked return values.
Code:
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void *thread_runner(void *index);
// pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
long array[100000000];
long sum = 0;
int main() {
/* Insert values in the array */
long i = 0;
for (i = 0; i < 100000000; i++) {
array[i] = i+1;
}
/* Declare thread variables */
pthread_t t1, t2, t3, t4;
int index1 = 0;
int index2 = 25000000;
int index3 = 50000000;
int index4 = 75000000;
/* Create 4 threads */
int rc = pthread_create(&t1, NULL, thread_runner, &index1);
rc = pthread_create(&t2, NULL, thread_runner, &index2);
rc = pthread_create(&t3, NULL, thread_runner, &index3);
rc = pthread_create(&t4, NULL, thread_runner, &index4);
/* Wait for threads to complete */
rc = pthread_join(t1, NULL);
rc = pthread_join(t2, NULL);
rc = pthread_join(t3, NULL);
rc = pthread_join(t4, NULL);
printf("Sum: %ld\n", sum);
return 0;
}
void *thread_runner(void *index) {
int i = 0;
int i_index = *((int*)index);
long local_sum = 0;
for (i = i_index; i < i_index+25000000; i++) {
local_sum += array[i];
}
// Do i need to lock the following statement ?
sum += local_sum;
}