This is the mail archive of the
pthreads-win32@sources.redhat.com
mailing list for the pthreas-win32 project.
Re: Question about condition variable
Hello jean,
first at all thank you for your help. Look at page 81 in the book
PTHREADS programming. There is a sample, how to deal with pthread
condition varaibles. The previosly described problem encounteres on
a single processor system with WINNT 4.0 also in this example. Try
this out fist without Sleep(0) line in inc_count function then
uncomment Sleep(0) and try it again you will see what happens.
What you can also try is to create first the watch_count thread, to
let him enter in to the while, so that pthread_cond_wait function
unlocks the count_mutex while waiting. Then start inc_count with
and whithout Sleep(0).
#include <stdio.h>
#include "pthread.h"
#define TCOUNT 10
#define WATCH_COUNT 12
int count=0 ;
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t count_treshold_cv = PTHREAD_COND_INITIALIZER;
int thread_ids[3] = {0,1,2};
void* watch_count(int *idp)
{
pthread_mutex_lock(&count_mutex) ;
while( count<=WATCH_COUNT){
pthread_cond_wait(&count_treshold_cv, &count_mutex);
printf( "watch_count(): Thread %d, count is %d\n", *idp, count);
}
pthread_mutex_unlock(&count_mutex) ;
return NULL ;
}
void* inc_count(int *idp)
{
int i;
for(i=0;i<TCOUNT; i++){
pthread_mutex_lock(&count_mutex) ;
count++;
printf( "inc_count(): Thread %d, old count %d,\
new count %d\n", *idp, count-1, count );
if(count==WATCH_COUNT)
pthread_cond_signal(&count_treshold_cv);
pthread_mutex_unlock(&count_mutex) ;
// Sleep(0) ; //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< uncomment
this line
}
return NULL ;
}
int main()
{
int i ;
pthread_t threads[3] ;
pthread_create( &threads[0],NULL,inc_count, &thread_ids[0] );
pthread_create( &threads[1],NULL,inc_count, &thread_ids[1] );
pthread_create( &threads[2],NULL,watch_count, &thread_ids[2] );
for(i=0; i<3; i++){
pthread_join(&threads[i],NULL) ;
}
getchar() ;
return 0;
}
What happens now? What is, if the signal from inc_count is not
treated early enough, before the next thread holds the count_mutex.
** Output with Sleep(0):
inc_count(): Thread 0, old count 0, new count 1
inc_count(): Thread 1, old count 1, new count 2
inc_count(): Thread 0, old count 2, new count 3
inc_count(): Thread 1, old count 3, new count 4
inc_count(): Thread 0, old count 4, new count 5
inc_count(): Thread 1, old count 5, new count 6
inc_count(): Thread 0, old count 6, new count 7
inc_count(): Thread 1, old count 7, new count 8
inc_count(): Thread 0, old count 8, new count 9
inc_count(): Thread 1, old count 9, new count 10
inc_count(): Thread 0, old count 10, new count 11
inc_count(): Thread 1, old count 11, new count 12
watch_count(): Thread 2, count is 12
inc_count(): Thread 0, old count 12, new count 13
inc_count(): Thread 1, old count 13, new count 14
inc_count(): Thread 0, old count 14, new count 15
inc_count(): Thread 1, old count 15, new count 16
inc_count(): Thread 0, old count 16, new count 17
inc_count(): Thread 1, old count 17, new count 18
inc_count(): Thread 0, old count 18, new count 19
inc_count(): Thread 1, old count 19, new count 20
** Output without Sleep(0):
inc_count(): Thread 0, old count 0, new count 1
inc_count(): Thread 0, old count 1, new count 2
inc_count(): Thread 0, old count 2, new count 3
inc_count(): Thread 0, old count 3, new count 4
inc_count(): Thread 0, old count 4, new count 5
inc_count(): Thread 0, old count 5, new count 6
inc_count(): Thread 0, old count 6, new count 7
inc_count(): Thread 0, old count 7, new count 8
inc_count(): Thread 0, old count 8, new count 9
inc_count(): Thread 0, old count 9, new count 10
inc_count(): Thread 1, old count 10, new count 11
inc_count(): Thread 1, old count 11, new count 12
inc_count(): Thread 1, old count 12, new count 13
inc_count(): Thread 1, old count 13, new count 14
inc_count(): Thread 1, old count 14, new count 15
inc_count(): Thread 1, old count 15, new count 16
inc_count(): Thread 1, old count 16, new count 17
inc_count(): Thread 1, old count 17, new count 18
inc_count(): Thread 1, old count 18, new count 19
inc_count(): Thread 1, old count 19, new count 20
here the watch_count thread could not enter into the while,
because it had no chance to get the count_mutex
** Output with watch_count created first and without Sleep(0):
inc_count(): Thread 0, old count 0, new count 1
inc_count(): Thread 0, old count 1, new count 2
inc_count(): Thread 0, old count 2, new count 3
inc_count(): Thread 0, old count 3, new count 4
inc_count(): Thread 0, old count 4, new count 5
inc_count(): Thread 0, old count 5, new count 6
inc_count(): Thread 0, old count 6, new count 7
inc_count(): Thread 0, old count 7, new count 8
inc_count(): Thread 0, old count 8, new count 9
inc_count(): Thread 0, old count 9, new count 10
inc_count(): Thread 1, old count 10, new count 11
inc_count(): Thread 1, old count 11, new count 12
inc_count(): Thread 1, old count 12, new count 13
inc_count(): Thread 1, old count 13, new count 14
inc_count(): Thread 1, old count 14, new count 15
inc_count(): Thread 1, old count 15, new count 16
inc_count(): Thread 1, old count 16, new count 17
inc_count(): Thread 1, old count 17, new count 18
inc_count(): Thread 1, old count 18, new count 19
inc_count(): Thread 1, old count 19, new count 20
watch_count(): Thread 2, count is 20
here the watch_count is not waked up early enough. But the program
semantic requeires the watch_count should be waked up when the
count variable reaches 12!
jean andre schrieb:
>
> Hello,
>
> Inside your thread, it sould waiting for a specfic signal and make
> broadcast the signal for every thread that running.
>
> For ex: inside all thread except the nain thread:
>
> for ever {
>
> wait until specific signal
> }
>
> in the main thread :
> post a message in queue thread.
> wake up thread by BROADCASITING message for all thread.
>
> --------------------------------------------------------------------
> EX : C++ code.
> Si Main thread and all other thread sshould wait on the same condion
> variable and mutex.
> A good sample how to deal with queue and threads can be found in the
> book :
> PTHREADS programming of O'Reilly, Nichols, Buttlar & Farell. ISBN-
> 1-56592-115-1
> Buy it, very good investisment !
> Hope, this help you.
>
> Waiting thread:
> -------------
> macro : SNS_COND_WAIT = pthread_cond_wait
> macro : SNS_COND_BROADCAST = pthread_cond_broadcast
>
> LONG BaseQueue::Q_WaitForEvent( VOID ) {
>
> while ( (m_lQueueSize == 0) && (!m_bQueueShutdown) ) {
>
> if ( SNS_COND_WAIT(&m_condQueueNotEmpty, &m_mutexQueueLock ) != 0 )
>
> return Q_LogError( m_szQName, SNSLOG_ERROR, SNS_E_SYS_COND_WAIT,
> "Q_WaitForEvent" );
> }
>
> return NO_ERROR;
> }
>
> Main thread:
> -----------
>
> if ( SNS_COND_BROADCAST(&m_condQueueNotEmpty) != 0 )
> Q_LogError( m_szQName, SNSLOG_ERROR, SNS_E_SYS_COND_BROADCAST,
> "Q_AddEvent" );
>
> --
> Jean
>
> Taci Ülker wrote:
> >
> > Hello all,
> >
> > I am developing a software based on win32-pthreads (latest available).
> > My problem I encountered is:
> >
> > I have an object for message queuing, wich is intended to let the
> > callers thread wait by getMessage(LPSSMSG lpMsg), until a new
> > message is posted by any other thread. Now imagine, the thread
> > which is waiting for new messages is in status ACTIVE (sleeping or
> > not running) in operating system. The thread wich is posting a new
> > message is in status RUNNING. This running thread pushes at first
> > a new message into the queue and signals the waiting thread to be
> > waked up and unlocks the mutex immediately, so that other threads
> > can push further new messages.
> >
> > Now, the problem is when the signal is given to wake up the waiting
> > thread by the first message pushing thread then the OS dont switch
> > automatically its thread execution. This means if the thread is not
> > waked up, because it is not switched to stutus RUNNING and an other
> > thread pushes further new message in to the queue and signals also
> > the waiting thread then what is about the first and second signals?
> >
> > I am actually switching thread execution with sleep(0) function,
> > after each message posting.
>
> --
> Jean ANDRE
> Tel: (514) 398-9799 #24 Fax: (514) 398-9353