This is the mail archive of the pthreads-win32@sources.redhat.com mailing list for the pthreas-win32 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]