检查pthread互斥锁是锁定还是解锁(线程锁定后)

我需要查看一个互斥锁是否在if语句中被锁定或解锁,所以我这样检查它…

if(mutex[id] != 2){ /* do stuff */ } 

但当我检查它时,gcc给我以下错误:

error: invalid operands to binary != (have 'ptherad_mutex_t' and 'int')

那么如何检查互斥锁是否被锁定?

编辑:

我的问题的一个关键组成部分是我的线程(按设计)在将控制传递给另一个线程后立即锁定自己。 因此,当线程A将控制传递给线程B时,线程A被锁定,线程B执行某些操作,然后当线程B完成时,它将解锁线程A.

这样做的问题是,如果线程B尝试解锁线程A并且线程A尚未完成锁定,则解锁的调用将丢失,线程A保持锁定状态,从而导致死锁。

更新:

我根据caf的建议重新制作了我的程序,但我仍遇到问题。 我已经将我的程序模拟到了尽可能最好的结构caf中,但我现在甚至无法分辨出导致死锁的原因……我在这里创建了一个新问题,寻求我的代码帮助。

以下是caf的建议的可运行版本。 我在线程a的函数中做了一个小的重新排序,没有它,线程a和线程b都会在创建时被锁定,等待一个永远不会改变的条件。

 #include  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); } } 

互斥体不是您想要实现的方案的正确原语。 你应该使用条件变量

 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); } 

每个线程将在pthread_cond_wait()阻塞,直到另一个线程发出信号唤醒它为止。 这不会死锁。

通过为每个线程分配一个intpthread_cond_tpthread_mutex_t ,它可以很容易地扩展到许multithreading。

您可以使用pthread_mutex_trylock 。 如果成功,互斥锁无人认领,你现在拥有它(所以你应该释放它并返回“unheld”,在你的情况下)。 否则,有人拿着它。

我必须强调,“检查互斥锁是否无人认领”是一个非常糟糕的主意。 这种思想存在固有的竞争条件。 如果这样的函数在时间t告诉你锁是未被保持的,那么对于其他一些线程是否在t+1获得锁定一无所知。

如果使用代码示例更好地说明,请考虑:

 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... } 

您无法将pthread_mutex_t与int进行比较。

您可以使用

int pthread_mutex_trylock(pthread_mutex_t * mutex);

检查一下。