Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 06 Aug 2005 16:54:21 +0200
From:      "Philip S. Schulz" <ph.schulz@gmx.de>
To:        freebsd-hackers@freebsd.org
Subject:   pthreads problem
Message-ID:  <42F4CF1D.5000501@gmx.de>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------010500080506060201080403
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi!

  From the what's-wrong-with-my-code department...

  I'm having trouble with two threads accessing a queue. One thread 
writes to it while the other one reads from the queue. I'd like the 
consumer to run until the main thread (which is the producer) decides 
that the consumer thread should exit.

  Let me show you some example code to illustrate what I'm currently 
doing. The consumer runs in an endless loop until it is being cancelled 
by the main thread using pthread_cancel():

void *thread_routine(void *args) {
   while (1) {
     pthread_mutex_lock(&m);

     if (len == 0)
       pthread_cond_wait(&notempty, &m);

     printf("consumer: %i\n", --len);

     pthread_cond_signal(&notfull);
     if (len == 0)
       pthread_cond_signal(&isempty);

     pthread_mutex_unlock(&m);
   }
   return (NULL);
}

  I belive the only cancellation point here is pthread_cond_wait(), so 
the main thread cancels the consumer while it is waiting on the notempty 
condition and the mutex m will not be destroyable.

   pthread_mutex_lock(&m);
   if (len > 0) {
     printf("Waiting for consumer...\n");
     pthread_cond_wait(&isempty, &m);
   }
   pthread_mutex_unlock(&m);

   pthread_cancel(t);
   pthread_join(t, NULL);

   pthread_cond_destroy(&notfull);
   pthread_cond_destroy(&notempty);
   pthread_cond_destroy(&isempty);

   error = pthread_mutex_destroy(&m);
   if (error)
     printf("%s\n", strerror(error));

If the main thread holds the mutex over both the pthread_cancel() and 
pthread_join() calls, a deadlock occurs where the consumer waits on the 
notempty condition and the main thread waits on the consumer:

   pthread_cancel(t);
   pthread_join(t, NULL);

   pthread_mutex_unlock(&m);

So, what is the best way to solve this problem? Introduce a variable for 
the while-loop like "while (running) { .. }"? Have the consumer poll if 
there is data in the queue?

I hope somebody can help me.

TIA,

Phil.

P.S:: Attached is the full example.

--------------010500080506060201080403--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?42F4CF1D.5000501>