我需要查看是否在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中,但是我甚至无法告诉现在导致死锁的原因...我已经创建了一个新问题here寻求帮助我的代码。
以下是caf的建议的可运行版本。我在线程a的函数中做了一个小的重新排序,没有它,线程a和线程b都会在创建时被锁定,等待一个永远不会改变的条件。
#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);
}
}
答案 0 :(得分:19)
您可以使用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...
}
答案 1 :(得分:18)
互斥体不是您要实现的方案的正确原语。您应该使用条件变量:
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()
中阻塞,直到另一个线程发出信号唤醒它为止。这不会死锁。
通过为每个线程分配一个int
,pthread_cond_t
和pthread_mutex_t
,可以轻松扩展到多个线程。
答案 2 :(得分:0)
您无法将pthread_mutex_t与int进行比较。
您可以使用
INT pthread_mutex_trylock(pthread_mutex_t *互斥);
检查一下。