public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* glibc and Thread synchronization
@ 2004-06-03 22:31 alexislefevre
  2004-06-04  0:27 ` Ishwar Rattan
  0 siblings, 1 reply; 3+ messages in thread
From: alexislefevre @ 2004-06-03 22:31 UTC (permalink / raw)
  To: gcc-help

/*
Hi all,
As I'm somewhat relatively new to Linux Threads, I 'm trying to get some help to
circumvent
the issue described below (though not 100% sure I knocked on the right door).
Plateform: linux 2.4.21-0.13mdk
]$gcc --version
gcc (GCC) 3.2.2 (Mandrake Linux 9.1 3.2.2-3mdk)
glibc-2.3.1-10.1.91mdk

To get appropriate thread synchronization, I'm using the usual mutex/condition
variable duo, that is:
Thread 0
              pthread_mutex_lock(&mut);
              pthread_cond_wait(&cond, &mut);
              ....do something on x,y ....
              pthread_mutex_unlock(&mut);
Thread 1
              pthread_mutex_lock(&mut);
	      ....do other things on x,y ....
              if (x > y) pthread_cond_signal(&cond);
              pthread_mutex_unlock(&mut);

The above code is inspired from "man pthread_cond_wait" output

In somecases, this snippet works as expected (if Thread 0 locks the  mutex
first). However, should thread 1
gets the lock on mutex "mut" first, and depending on the timeslice assigned to
each thread (over which there is very few control at the user level),
it can happen that Thread 0 never get the condition signaled. For example:

Thread 1 is getting the lock on muttex mut first
Thread 0 tries to lock mut; as it is already locked, the thread is put asleep.
Thread 1 do the job; when done, the condition is signaled, and the mutex is
unlocked.

However, since there was no thread waiting for the condition when it was
signaled, nothing happens, and thread 0
gets stuck on pthread_cond_wait(&cond, &mut). On my system, the behavior is the
same if pthread_cond_signal(&cond)
is called after pthread_mutex_unlock(&mut), or if I loop in a _trylock in Thread
0. The only solution I found is
to change :
              pthread_mutex_lock(&mut);
	      ....do other things on x,y ....
              if (x > y) pthread_cond_signal(&cond);
              pthread_mutex_unlock(&mut);
into
              pthread_mutex_lock(&mut);
	      ....do other things on x,y ....
              pthread_mutex_unlock(&mut);
	      usleep(1);
              if (x > y) pthread_cond_signal(&cond);

But this is obviously not a smart solution, since x and y could be modified as
soon as the mutex is unlock.

I think this issue is intrisinc to linux thread design, since the signal is lost
if there is no thread waiting
for it. However, this is still enoying because, in my view, it breaks the
expected deterministic behavior
resulting from thread synchronization. I've added below a small, dummy code,
that reproduces the problem.

What I'm looking for is a condition that remains signaled until a thread
eventually reset it (equivalent to an
event in windows world). Has anyone ever found the trick or succeeded into
circumventing this problem ?
Any imputs are most welcomed

Alexis

*/
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *thread_function(void *);
void *thread_reader(void *);
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int  counter = 0;
void  *thread_function(void* p)
{
   pthread_mutex_lock( &mutex1 );
   fprintf(stdout,"Thread number %ld WAITING CONDITION for counter \n",
pthread_self());fflush(stdout);
   pthread_cond_wait(&cond,&mutex1);
   counter++;
   pthread_mutex_unlock( &mutex1 );
   fprintf(stdout,"Thread number %ld has INCREMENTED counter \n",
pthread_self());fflush(stdout);
   pthread_exit((void*)0);
}
void  *thread_reader(void* p)
{  
   pthread_mutex_lock( &mutex1 );
   fprintf(stdout,"Thread number %ld is READING counter %d\n", pthread_self(),
counter);fflush(stdout);
   pthread_mutex_unlock( &mutex1 );
   //usleep(1); /* required for thread_function to have condition cond signaled...*/
   pthread_cond_signal(&cond);
   fprintf(stdout,"Thread number %ld has RED counter %d\n", pthread_self(),
counter);fflush(stdout);

   pthread_exit((void*)0);
}

int main(int argc, char *argv[])
{
  #define NTHREADS 2
  int status,rc;
  void * (*f0)(void* args);
  void * (*f1)(void* args);
  pthread_t thread_id[NTHREADS];
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);


  /* Substitute f1,f0 address to see the stuff */
  f1 = thread_function;
  f0 = thread_reader;


		rc = pthread_create( &thread_id[0], &attr, f0, NULL );
			if (rc)
		{
			printf("ERROR; return code from pthread_create  is %d\n", rc);
			exit(-1);
		}

		rc = pthread_create( &thread_id[1], &attr, f1, NULL );
				if (rc)
		{
			printf("ERROR; return code from pthread_create  is %d\n", rc);
			exit(-1);
		}
	/** Joignin the thread*/
  	 pthread_attr_destroy(&attr);
		rc = pthread_join(thread_id[0], (void **)&status);
		if (rc)
		{
			printf("ERROR; return code from pthread_join()  is %d for thread %ld\n",
rc,thread_id[0]);
			exit(-1);
		}
      printf("Completed join with thread %ld status= %d\n",thread_id[0],
status);fflush(stdout);

		rc = pthread_join(thread_id[1], (void **)&status);
		if (rc)
		{
			printf("ERROR; return code from pthread_join()  is %d for thread %ld\n",
rc,thread_id[1]);
			exit(-1);
		}
     printf("Completed join with thread %d status= %d\n",thread_id[1],
status);fflush(stdout);



   printf("Final counter value: %d\n", counter);
   }


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: glibc and Thread synchronization
  2004-06-03 22:31 glibc and Thread synchronization alexislefevre
@ 2004-06-04  0:27 ` Ishwar Rattan
  2004-06-04  2:28   ` alexislefevre
  0 siblings, 1 reply; 3+ messages in thread
From: Ishwar Rattan @ 2004-06-04  0:27 UTC (permalink / raw)
  To: gcc-help



On Fri, 4 Jun 2004 alexislefevre@free.fr wrote:

> I think this issue is intrisinc to linux thread design, since the signal
> is lost if there is no thread waiting
That is correct behavior.

You are using calls to POSIX threads and have nothing to do with
gcc or Linux.

> for it. However, this is still enoying because, in my view, it breaks the
> expected deterministic behavior resulting from thread synchronization.

Welcome to concurrent programming!
Try your question on comp.programming.threads for an explaination.

-ishwar

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: glibc and Thread synchronization
  2004-06-04  0:27 ` Ishwar Rattan
@ 2004-06-04  2:28   ` alexislefevre
  0 siblings, 0 replies; 3+ messages in thread
From: alexislefevre @ 2004-06-04  2:28 UTC (permalink / raw)
  To: Ishwar Rattan; +Cc: gcc-help


> Welcome to concurrent programming!
> Try your question on comp.programming.threads for an explaination.
You're right, this shoud be more appropriate.
Thanks !

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2004-06-04  2:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-03 22:31 glibc and Thread synchronization alexislefevre
2004-06-04  0:27 ` Ishwar Rattan
2004-06-04  2:28   ` alexislefevre

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).