Mutexes are not the right primitive for the scheme that you want to implement. You should be using condition variables.
Mutexes are not the right primitive for the scheme that you want to implement. You should be using condition variables: int run_thread_a = 0; pthread_mutex_t run_lock_a = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t run_cond_a = PTHREAD_COND_INITIALIZER; int run_thread_b = 0; pthread_mutex_t run_lock_b = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t run_cond_b = PTHREAD_COND_INITIALIZER; /* thread A */ while (1) { /* Wait for Thread A to be runnable */ pthread_mutex_lock(&run_lock_a); while (!run_thread_a) pthread_cond_wait(&run_cond_a, &run_lock_a); run_thread_a = 0; pthread_mutex_unlock(&run_lock_a); /* Do some work */ /* Now wake thread B */ pthread_mutex_lock(&run_lock_b); run_thread_b = 1; pthread_cond_signal(&run_cond_b); pthread_mutex_unlock(&run_lock_b); } /* thread B */ while (1) { /* Wait for Thread B to be runnable */ pthread_mutex_lock(&run_lock_b); while (!run_thread_b) pthread_cond_wait(&run_cond_b, &run_lock_b); run_thread_b = 0; pthread_mutex_unlock(&run_lock_b); /* Do some work */ /* Now wake thread A */ pthread_mutex_lock(&run_lock_a); run_thread_a = 1; pthread_cond_signal(&run_cond_a); pthread_mutex_unlock(&run_lock_a); } Each thread will block in pthread_cond_wait() until the other thread signals it to wake up. This will not deadlock.It can easily be extended to many threads, by allocating one int, pthread_cond_t and pthread_mutex_t per thread.
Caf I had originally tried using a condition, but my threads need to run concurrently, and unless I want to make a condition for each one (an array of conditions will not work because it would be blocked each time it was accessed by any thread, thus eliminating the desired concurrency) I do not see how I can make this work. – typoknig Dec 6 '10 at 6:51 @typoknig: An array of conditions is exactly what you need. It will not be "blocked each time it was accessed by any thread".
Each condition variable is independent - it does not matter whether you keep them in an array or in separate named globals. – caf Dec 6 '10 at 12:07 @caf I have updated my question and added my code, perhaps you might take a look at it. I know the structure you have suggested is correct, but I still cannot get it to work right (see updated question).
The code I have posted is completely rewritten from when I asked my question (now using condition). – typoknig Dec 7 '10 at 5:03 @typoknig: I'll have a look, but you may be better off to post the new code as a new question. – caf Dec 7 '10 at 5:29 @caf I made a new question as you suggested, thanks for your help.
– typoknig Dec 7 '10 at 21:30.
You can use pthread_mutex_trylock. If that succeeds, the mutex was unclaimed and you now own it (so you should release it and return "unheld", in your case). Otherwise, someone is holding it.
I have to stress though that "check to see if a mutex is unclaimed" is a very bad idea. There are inherent race conditions in this kind of thinking. If such a function tells you at time t that the lock is unheld, that says absolutely nothing about whether or not some other thread acquired the lock at t+1.In case this is better illustrated with a code example, consider: bool held = is_lock_held(); if (!held) { // What exactly can you conclude here?
Pretty much nothing. // It was unheld at some point in the past but it might be held // by the time you got to this point, or by the time you do your // next instruction... }.
Asveikau my problem is that I have a thread (a) that passes control to another thread (b) then locks itself. Once thread be is done it unlocks thread a then locks itself. The system works great but on rare occasion thread be "unlocks" thread a before thread a locks itself, thus the "unlock" is lost and the program dead locks.
I have tried to use trylock but not the way you suggested... I will try again. – typoknig Dec 6 '10 at 1:29 @typoknig - It sounds like you should consider a simpler synchronization scheme. For example, you could have B signal a semaphore that A waits on.
– asveikau Dec 6 '10 at 1:33 @asveikau the issue is that thread A has control and must lock itself, and I have no control over how fast it locks itself. B does signal/unlock the semaphore for thread A, when thread B is done, but if thread A has not yet locked itself (and does so after thread B has signaled for the unlock) the thread A will remain locked. – typoknig Dec 6 '10 at 1:39 1 Is there a reason the threads can't just share one mutex?
Thread A releases the mutex, yields the CPU, and then waits on the mutex again. Thread B will be woken up when A releases, will take the mutex, and then there's no notify-before-wait problem. – Anon.
Dec 6 '10 at 1:42 I have many threads and (like A10 and B10) which are not paired together, but are depended on each other. For instance thread A1 might be dependent on thread B5 this loop, but the next loop it might be dependent on thread B7 or some other thread. – typoknig Dec 6 '10 at 1:48.
You can't compare a pthread_mutex_t with a int. You can use int pthread_mutex_trylock(pthread_mutex_t *mutex); to check that.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.