#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t condition_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_cond = PTHREAD_COND_INITIALIZER;
void *functionCount1();
void *functionCount2();
int count = 0;
#define COUNT_DONE 10
#define COUNT_HALT1 3
#define COUNT_HALT2 6
int main()
{
pthread_t thread1, thread2;
pthread_create( &thread1, NULL, &functionCount1, NULL);
pthread_create( &thread2, NULL, &functionCount2, NULL);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
return 0;
}
void *functionCount1()
{
for(;;)
{
pthread_mutex_lock( &condition_mutex );
while( count >= COUNT_HALT1 && count <= COUNT_HALT2 )
{
pthread_cond_wait( &condition_cond, &condition_mutex );
}
pthread_mutex_unlock( &condition_mutex );
pthread_mutex_lock( &count_mutex );
count++;
printf("Counter value functionCount1: %d\n",count);
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) return(NULL);
}
}
void *functionCount2()
{
for(;;)
{
pthread_mutex_lock( &condition_mutex );
if( count < COUNT_HALT1 || count > COUNT_HALT2 )
{
pthread_cond_signal( &condition_cond );
}
pthread_mutex_unlock( &condition_mutex );
pthread_mutex_lock( &count_mutex );
count++;
printf("Counter value functionCount2: %d\n",count);
pthread_mutex_unlock( &count_mutex );
if(count >= COUNT_DONE) return(NULL);
}
}
g++ gives error:
/home/C/test/main.cpp|96|error: invalid conversion from ‘void* (*)()’
to ‘void* (*)(void*)’|
/home/C/test/main.cpp|96|error: initializing argument 3 of ‘int
pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*),
void*)’|
/home/C/test/main.cpp|97|error: invalid conversion from ‘void* (*)()’
to ‘void* (*)(void*)’|
/home/C/test/main.cpp|97|error: initializing argument 3 of ‘int
pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*),
void*)’|
Tim schrieb:
> g++ gives error:
>
> /home/C/test/main.cpp|96|error: invalid conversion from ‘void* (*)()’
> to ‘void* (*)(void*)’|
> /home/C/test/main.cpp|96|error: initializing argument 3 of ‘int
> pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*),
> void*)’|
> /home/C/test/main.cpp|97|error: invalid conversion from ‘void* (*)()’
> to ‘void* (*)(void*)’|
> /home/C/test/main.cpp|97|error: initializing argument 3 of ‘int
> pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*),
> void*)’|
>
change
> void *functionCount1();
> void *functionCount2();
to
void *functionCount1(void*);
void *functionCount2(void*);
best regards
Torsten
--
kostenlose Wirtschaftssimulation: http://www.financial-rumors.de
[ ... ]
>void *functionCount1();
>void *functionCount2();
These prototypes don't agree with
> pthread_create( &thread1, NULL, &functionCount1, NULL);
> pthread_create( &thread2, NULL, &functionCount2, NULL);
the argument type that is expected to pthread_create().
The pthread_* functions are C language. The C++ prototype for
a thread function is
extern "C" void *thread_function(void *);
Enjoy,
--
Steve Watt KD6GGD PP-ASEL-IA ICBM: 121W 56' 57.5" / 37N 20' 15.3"
Internet: steve @ Watt.COM Whois: SW32-ARIN
Free time? There's no such thing. It just comes in varying prices...
Others have pointed out the mistake that caused you to post. However,
you have a very serious misunderstanding about how to use condition
variables:
> void *functionCount1()
> {
> for(;;)
> {
> pthread_mutex_lock( &condition_mutex );
> while( count >= COUNT_HALT1 && count <= COUNT_HALT2 )
> {
> pthread_cond_wait( &condition_cond, &condition_mutex );
> }
The point of the 'while' loop is to keep looping until you know the
condition is true. You check it again when 'pthread_cond_wait' returns
because just because it was true in the past doesn't mean it's true in
the future.
The whole point of this code is to make absolutely sure that the
following code does not execute unless the condition is true.
> pthread_mutex_unlock( &condition_mutex );
Whoops! You just unlocked the mutex. Now the condition may no longer
be true. This completely defeats the point of the 'while' loop as the
code below here may run whether or not the condition is true.
> pthread_mutex_lock( &count_mutex );
> count++;
> printf("Counter value functionCount1: %d\n",count);
> pthread_mutex_unlock( &count_mutex );
>
> if(count >= COUNT_DONE) return(NULL);
> }
> }
Why do you have two mutexes, both protecting the count?
And now you can see your 'while' loop is busted too:
> void *functionCount2()
> {
> for(;;)
> {
> pthread_mutex_lock( &condition_mutex );
> if( count < COUNT_HALT1 || count > COUNT_HALT2 )
> {
> pthread_cond_signal( &condition_cond );
> }
> pthread_mutex_unlock( &condition_mutex );
>
> pthread_mutex_lock( &count_mutex );
> count++;
Here, you modify 'count' without holding the condition_mutex. But the
other thread *reads* 'count' holding only the condition mutex. Boom.
One thread may not modify a variable while another thread is or may be
reading it. This thread may modify 'count' while the first thread is
reading it in the 'while' loop.
> printf("Counter value functionCount2: %d\n",count);
> pthread_mutex_unlock( &count_mutex );
>
> if(count >= COUNT_DONE) return(NULL);
> }
>
> }
You must use the same mutex to protect the predicate as you acquire/
release with the condition variable. Otherwise, the code makes no
sense.
DS