Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check to see if a pthread mutex is locked or unlocked (After a thread has locked itself)

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);
    }
}
like image 868
ubiquibacon Avatar asked Dec 06 '10 01:12

ubiquibacon


People also ask

Can you check if a mutex is locked?

Although you can Lock() or Unlock() a mutex, you can't check whether it's locked.

What happens if you try to lock a mutex that is already locked?

If the mutex is already locked by another thread, the thread waits for the mutex to become available. The thread that has locked a mutex becomes its current owner and remains the owner until the same thread has unlocked it.

What happens if you unlock a mutex that is already unlocked?

If a thread attempts to unlock a mutex that it has not locked or a mutex that is unlocked, an error is returned. If the mutex type is PTHREAD_MUTEX_DEFAULT, attempting to unlock the mutex if it was not locked by the calling thread results in undefined behavior.

Can a mutex be locked in one thread and unlocked in another?

If the mutex is unlocked, the subroutine locks it. If the mutex is already locked by another thread, the subroutine blocks the calling thread until the mutex is unlocked. If the mutex is already locked by the calling thread, the subroutine might block forever or return an error depending on the type of mutex.


1 Answers

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...
}
like image 80
asveikau Avatar answered Oct 12 '22 19:10

asveikau