MultiThreading (pthread) Interview Question -2
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
int glob = 0;
void *threadFunc(void *arg)
{
int j;
int loops = *((int *) arg);
printf("\n %s: \n",__func__);
for (j = 0; j < loops; j++)
{
glob++;
}
return NULL;
}
int main()
{
pthread_t t1, t2;
int loops=1000000, ret;
ret = pthread_create(&t1, NULL, threadFunc, &loops);
if (ret != 0)
perror("Pthread Create : ");
ret = pthread_create(&t2, NULL, threadFunc, &loops);
if (ret != 0)
perror("Pthread Create: ");
ret = pthread_join(t1, NULL);
if (ret != 0)
perror("Pthread Join: ");
ret = pthread_join(t2, NULL);
if (ret != 0)
perror("Pthread Join : ");
printf("glob = %d\n", glob);
return 0;
}
What is the expected output of the program?
Ans: 2*loops
If you say the above answer it is wrong, because the increment is not an atomic operation. Increment when converted to assembly will not be in single instruction.Hence the difference
One way to solve is to make increment atomic. This can be done by using atomic operator provided by GNU.
Replace the instruction glob++ with __sync_fetch_and_add(&glob, 1); Now we will get our desired output.
#include <stdio.h>
#include <stdlib.h>
int glob = 0;
void *threadFunc(void *arg)
{
int j;
int loops = *((int *) arg);
printf("\n %s: \n",__func__);
for (j = 0; j < loops; j++)
{
glob++;
}
return NULL;
}
int main()
{
pthread_t t1, t2;
int loops=1000000, ret;
ret = pthread_create(&t1, NULL, threadFunc, &loops);
if (ret != 0)
perror("Pthread Create : ");
ret = pthread_create(&t2, NULL, threadFunc, &loops);
if (ret != 0)
perror("Pthread Create: ");
ret = pthread_join(t1, NULL);
if (ret != 0)
perror("Pthread Join: ");
ret = pthread_join(t2, NULL);
if (ret != 0)
perror("Pthread Join : ");
printf("glob = %d\n", glob);
return 0;
}
What is the expected output of the program?
Ans: 2*loops
If you say the above answer it is wrong, because the increment is not an atomic operation. Increment when converted to assembly will not be in single instruction.Hence the difference
One way to solve is to make increment atomic. This can be done by using atomic operator provided by GNU.
Replace the instruction glob++ with __sync_fetch_and_add(&glob, 1); Now we will get our desired output.
Comments
Post a Comment