I need to see if a mutex is locked or unlocked in an if statement so I check it like this...
if(mutex[id] != 2){
/* do stuff */
}
but when I check it gcc gives me the following error:
error: invalid operands to binary != (have 'ptherad_mutex_t' and 'int')
So how can I check to see if the mutex is locked or not?
EDIT:
A key component to my problem is that my threads (by design) lock themselves right AFTER passing control to another thread. So when thread A passes control to thread B thread A is locked, thread B does some stuff, then when thread B is done it will unlock thread A.
The problem with this is that if thread B attempts to unlock thread A and thread A has not yet completed locking itself then the call to unlock is lost and thread A remains locked which causes a dead lock.
UPDATE:
I remade my program taking caf's suggestion but I am still running into problems. I have molded my program into the structure caf provided the best I can but I cannot even tell what is causing the dead lock now... I have created a new question here seeking help with my code.
Below is a runnable version of caf's suggestion. I made a small reordering in the function for thread a, without which both thread a and thread b would have been locked upon their creation, waiting for a condition that could never change.
#include <pthread.h>
int run_a = 0;
pthread_mutex_t lock_a = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_a = PTHREAD_COND_INITIALIZER;
int run_b = 0;
pthread_mutex_t lock_b = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_b = PTHREAD_COND_INITIALIZER;
void *a(void *);
void *b(void *);
int main(){
int status;
pthread_t thread_a;
pthread_t thread_b;
pthread_create(&thread_a, NULL, a, (void *)0);
pthread_create(&thread_b, NULL, b, (void *)0);
pthread_join(thread_a, (void **)&status);
pthread_join(thread_b, (void **)&status);
}
/* thread A */
void *a(void *i){
while (1) {
printf("thread A is running\n");
sleep(1);
/* unlock thread B */
pthread_mutex_lock(&lock_b);
run_b = 1;
pthread_cond_signal(&cond_b);
pthread_mutex_unlock(&lock_b);
/* wait for thread A to be runnable */
pthread_mutex_lock(&lock_a);
while (!run_a)
pthread_cond_wait(&cond_a, &lock_a);
run_a = 0;
pthread_mutex_unlock(&lock_a);
}
}
/* thread B */
void *b(void *i){
while (1) {
/* wait for thread B to be runnable */
pthread_mutex_lock(&lock_b);
while (!run_b)
pthread_cond_wait(&cond_b, &lock_b);
run_b = 0;
pthread_mutex_unlock(&lock_b);
printf("thread B is running\n");
sleep(1);
/* unlock thread A */
pthread_mutex_lock(&lock_a);
run_a = 1;
pthread_cond_signal(&cond_a);
pthread_mutex_unlock(&lock_a);
}
}
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...
}