Hello, PTHREAD_COND_WAIT(3) is precise but easy to misread.
It first say it will unlock the mutex given as a second argument, and after talking about the rest say it will be locked again. This second lock it supposed to have a particular usage, reading documentation about this i found a stackoverflow answer that is very clear : http://stackoverflow.com/questions/2763714/why-do-pthreads-condition-variable-functions-require-a-mutex g+ community was talking about this book : http://pragprog.com/book/pb7con/seven-concurrency-models-in-seven-weeks is there an exemple inside ? My poor brain is not even to produce something 'good': #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <err.h> #include <unistd.h> #include <sys/queue.h> #define NTHREADS 7 int on = 1; pthread_cond_t jobs_signal = PTHREAD_COND_INITIALIZER; pthread_mutex_t jobs_lock = PTHREAD_MUTEX_INITIALIZER; struct job { int type; SIMPLEQ_ENTRY(job) entries; }; void *consumer(void *parm) { int rc; struct job* current_job; SIMPLEQ_HEAD(jobhead, job) *jobs_queue = (struct jobhead*)parm; while (on) { rc = pthread_mutex_lock(&jobs_lock); warn("consumer thread control code, lock:%d", rc); while (SIMPLEQ_EMPTY(jobs_queue) && on) { warn("consumer thread is waiting"); rc = pthread_cond_wait(&jobs_signal, &jobs_lock); warn("consumer thread received signal %d", rc); } if (on == 0) { pthread_mutex_unlock(&jobs_lock); pthread_cond_broadcast(&jobs_signal); //FIXME: OF course only one thread is waiting so must resignal.... return NULL; } current_job = SIMPLEQ_FIRST(jobs_queue); SIMPLEQ_REMOVE_HEAD(jobs_queue, entries); warn("consume jobs_queue one at a time here: %X", current_job->type); rc = pthread_mutex_unlock(&jobs_lock); warn("consumer pthread_mutex_lock(): %d", rc); warn("consume jobs_queue in each threads at the time here: %X", current_job->type); free(current_job); } return NULL; } int main(int argc, char **argv) { int rc=0; int i; pthread_t threadid[NTHREADS]; struct job* new_job; SIMPLEQ_HEAD(jobhead, job) jobs = SIMPLEQ_HEAD_INITIALIZER(jobs); printf("Create %d threads\n", NTHREADS); for(i=0; i<NTHREADS; ++i) { rc = pthread_create(&threadid[i], NULL, consumer, &jobs); warn("pthread_create(,,consumer,jobs) : %d", rc); } //lets produce i = 50; while (--i) { new_job = malloc(sizeof(struct job)); if (new_job == 0) err(3, "cant malloc"); new_job->type = rand(); rc = pthread_mutex_lock(&jobs_lock); warn("producer thread create job: (lock)%d, type %X", rc, new_job->type); SIMPLEQ_INSERT_TAIL(&jobs, new_job, entries); pthread_cond_signal(&jobs_signal); rc = pthread_mutex_unlock(&jobs_lock); warn("producer pthread_mutex_lock(): %d", rc); } while (0xBAD) { sleep(1); rc = pthread_mutex_lock(&jobs_lock); if (SIMPLEQ_EMPTY(&jobs)) break; rc = pthread_mutex_unlock(&jobs_lock); } rc = pthread_mutex_unlock(&jobs_lock); //quit on = 0; pthread_cond_broadcast(&jobs_signal); warn("waiting for threads..."); for (i=0; i<NTHREADS; ++i) { rc = pthread_join(threadid[i], NULL); } warn("cleaning locks..."); pthread_cond_destroy(&jobs_signal); pthread_mutex_destroy(&jobs_lock); warn("exit"); return 0; } -- --------------------------------------------------------------------------------------------------------------------- () ascii ribbon campaign - against html e-mail /\