/* 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); }