C program on POSIX Threads Synchronization
POSIX Threads provide multiple flows of execution within a
process. The threads have their own stacks but share the global data and heap.
So the global variables are visible to multiple threads. Also, the threads need
to synchronize their actions so that they jointly realize the overall
objectives of the process they belong to. The core problems of concurrent
programming, mutual exclusion and synchronization are relevant for threads just
like these problems are relevant for multi-process systems.
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
pthread_t tid[2];
int counter;
void* doSomeThing(void *arg)
{
unsigned long i = 0;
counter += 1;
printf("\n Job %d started\n", counter);
for(i=0; i<(0xFFFFFFFF);i++);
printf("\n Job %d finished\n", counter);
return NULL;
}
int main(void)
{
int i = 0;
int err;
while(i < 2)
{
err = pthread_create(&(tid[i]),
NULL, &doSomeThing, NULL);
if (err != 0)
printf("\ncan't
create thread :[%s]", strerror(err));
i++;
}
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
return 0;
}
###################################################################################################################
The above code is a simple
one in which two threads(jobs) are created and in the start function of these
threads, a counter is maintained through which user gets the logs about job
number which is started and when it is completed.
###################################################################################################################
The code and the flow looks fine but when we see the output :
$ ./tgsthreads
Job 1 started
Job 2 started
Job 2 finished
Job 2 finished
If you focus on the last two logs, you
will see that the log ‘Job 2 finished’ is repeated twice while no log for ‘Job
1 finished’ is seen.
Now, if you go back at the code and try
to find any logical flaw, you’ll probably not find any flaw easily. But if
you’ll have a closer look and visualize the execution of the code, you’ll
find that :
The log ‘Job 2 started’ is printed just
after ‘Job 1 Started’ so it can easily be concluded that while thread 1
was processing the scheduler scheduled the thread 2.
If the above assumption was true then the value of the ‘counter’
variable got incremented again before job 1 got finished.
So, when Job 1 actually got finished, then
the wrong value of counter produced the log ‘Job 2 finished’ followed by the
‘Job 2 finished’ for the actual job 2 or vice versa as it is dependent on
scheduler.
So, we see that its not the repetitive log but the wrong value of
the ‘counter’ variable that is the problem.
The actual problem was the usage of the variable ‘counter’ by
second thread when the first thread was using or about to use it. In other
words we can say that lack of synchronization between the threads while using
the shared resource ‘counter’ caused the problems or in one word we can say
that this problem happened due to ‘Synchronization problem’ between two
threads.