I am having a hard time getting mutexes to work…
Here’s some code I got from your website, and modified for my testing:
#include <stdio.h>
#include <pthread.h>
// create a mutex
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// a global variable (we want to protect)
int count = 0;
// thread1
void* function1( void* arg )
{
int tmp = 0;
int i;
int old1, old2;
while( 1 ) {
if(pthread_mutex_lock(&mutex) == -1)
{
perror(“pthread_mutex_lock Error”);
}
// supposedly protected code
old1 = tmp;
tmp = ++count;
old2 = tmp;
pthread_mutex_unlock(&mutex);
// Error or not?
// I expect old1 NOT to equal old2…
if (old1 == old2)
printf(“inc ERROR %d %d\n”, old1, old2);
else
printf(“inc OK %d %d\n”, old1, old2);
printf( “Count is %d\n”, tmp );
// snooze for a time
delay( 200 );
}
return 0;
}
// thread2
void* function2( void* arg )
{
int tmp = 0;
int i;
int old1, old2;
while( 1 ) {
if(pthread_mutex_lock(&mutex) == -1)
{
perror(“pthread_mutex_lock Error”);
}
// supposedly protected code
old1 = tmp;
tmp = --count;
old2 = tmp;
pthread_mutex_unlock(&mutex);
// I expect old1 NOT to equal old2…
if (old1 == old2) printf(“dec ERROR *********\n");
printf( " Count is %d\n”, tmp );
// snooze for a time
delay( 500 );
}
return 0;
}
int main( void )
{
pthread_create( NULL, NULL, &function1, NULL );
pthread_create( NULL, NULL, &function2, NULL );
// Let the threads run for 60 seconds.
sleep( 60 );
// destroy the mutex
pthread_mutex_destroy(&mutex);
return 0;
}
When I run it, I (unexpectedly) get:
inc OK 0 1
Count is 1
dec ERROR ***********
** Count is 0
inc ERROR 1 1
Count is 1
inc OK 1 2
Count is 2
** Count is 1
inc ERROR 2 2
Count is 2
inc OK 2 3
Count is 3
** Count is 2
inc ERROR 3 3
Count is 3
inc OK 3 4
Count is 4
** Count is 3
inc ERROR 4 4
Count is 4
inc OK 4 5
Count is 5
** Count is 4
inc ERROR 5 5
Could anyone explain why is this happening?
My understanding is that locking the mutex will ‘lock’ all operations in a
section of code, until the mutex is unlocked. Is this incorrect? (i guess
so, but…) What is the correct way to do this?
Thanks,
Mark