#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#define max_thread 5
int d = 0;
pthread_t thread_id[max_thread];
//the thread function definition
static void* thread_func(void* data){
for(int i = 0; i < 100000; i++){
d++;
}
return NULL;
}
int main(){
int rc, i, n;
n = 5;
//creating n=5 threads
for(i = 0; i < 5; i++){
rc = pthread_create(&thread_id[i], NULL, thread_func, NULL);
if(rc){
printf("\n ERROR %d \n", rc);
exit(1);
}
}
//waiting for the threads to finish execution
for(i = 0; i < 5; i++){
pthread_join(thread_id[i], NULL);
}
//printing value of global variable d
printf("counter = %d\n", d);
return 0;
}
What should be the output of this code? When I execute it, it is giving some arbitrary values (<<500000).
I understand that the critical section(in this case - updating the value of d) of the thread should be locked when it is being executed in a thread. But if I see it as a whole, saying that the variable d is being incremented 5,00,000 times, is it wrong? If I add 1, 500000 times shouldn't the answer be 500000 irrespective of the order of addition?
Please explain where am I going wrong in the concept?
The code invokes undefined behavior per 5.1.2.4 Multi-threaded executions and data races, p25:
The execution of a program contains a data race if it contains two conflicting actions in different threads, at least one of which is not atomic, and neither happens before the other. Any such data race results in undefined behavior.
As already noted in the comments, d++
is not an atomic operation since it involves at least three separate steps: read the value from memory, increment the variable, then store the new value into memory. Trying to perform that series of operations from multiple threads results in a race condition per 5.1.2.4p25 and invokes undefined behavior.
Thus there is no "correct" result.