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);
}
}
Mutexes are not the right primitive for the scheme that you want to implement. You should be using condition variables:
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
andpthread_mutex_t
per thread.You can't compare a pthread_mutex_t with a int.
You can use
to check that.
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 att+1
.In case this is better illustrated with a code example, consider: