Reputation: 4737
Sorry just found this code here - http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html and the mutex was explained with this code, but it has gone a little over my head. I understand the function of the mutex, and that it protects a shared variable during its critical section. The specifics here are confusing me though! By my understanding, we are creating a new thread with pthread_create, it's running the functionC process, which increments a counter. The counter is the protected variable, and, since both functions are running concurrently, the counter would return the wrong value if it was not protected by the mutex.
Is this correct/close ? Thanks a lot :).
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *functionC();
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
main()
{
int rc1, rc2;
pthread_t thread1, thread2;
/* Create independent threads each of which will execute functionC */
if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) )
{
printf("Thread creation failed: %d\n", rc1);
}
if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) )
{
printf("Thread creation failed: %d\n", rc2);
}
/* Wait till threads are complete before main continues. Unless we */
/* wait we run the risk of executing an exit which will terminate */
/* the process and all threads before the threads have completed. */
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
exit(0);
}
void *functionC()
{
pthread_mutex_lock( &mutex1 );
counter++;
printf("Counter value: %d\n",counter);
pthread_mutex_unlock( &mutex1 );
}
Upvotes: 1
Views: 243
Reputation: 5966
Yes, you are correct. The mutex is preventing the threads from stepping on each other when they try to increment the counter.
Since the increment operator is not necessarily an atomic operation (see here for more info), incrementing the same variable from multiple threads can lead to unexpected results. The mutex prevents this from happening by only allowing one thread at a time to increment the counter.
The join statements at the end just make sure that the main program and both threads all exit at the same time. Otherwise the main program would exit and the threads would be left hanging.
Upvotes: 1
Reputation: 181380
If you don't have the mutex in place, this is what might happen:
// initialization
counter = 0;
// thread 1 runs:
counter++;
// context switch
// thread 2 runs:
counter++;
// context switch
// thread 1 runs and printf "Counter value: 2"
printf("Counter value: %d\n",counter);
// context switch
// thread 2 runs and printf "Counter value: 2"
printf("Counter value: %d\n",counter);
So, you might end up with this output:
Counter value: 2
Counter value: 2
Now, with the mutex in place, you make sure that the increment and its print will run atomically, so you are 100% sure that the output will be:
Counter value: 1
Counter value: 2
But never:
Counter value: 2
Counter value: 2
Upvotes: 3
Reputation: 57268
Your explanation is exactly right. If more than one thread attempted to modify counter
at the same time, an update could be lost.
Upvotes: 3