C语言 检查 pthread 互斥锁是锁定还是解锁(在线程锁定自身之后)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4362459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check to see if a pthread mutex is locked or unlocked (After a thread has locked itself)
提问by ubiquibacon
I need to see if a mutex is locked or unlocked in an if statement so I check it like this...
我需要在 if 语句中查看互斥锁是锁定还是解锁,所以我像这样检查它...
if(mutex[id] != 2){
/* do stuff */
}
but when I check it gcc gives me the following error:
但是当我检查它时,gcc 给了我以下错误:
error: invalid operands to binary != (have 'ptherad_mutex_t' and 'int')
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.
我的问题的一个关键组成部分是我的线程(按设计)在将控制权传递给另一个线程后立即锁定自己。因此,当线程 A 将控制权传递给线程 B 时,线程 A 被锁定,线程 B 执行某些操作,然后当线程 B 完成时,它将解锁线程 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.
这样做的问题是,如果线程 B 尝试解锁线程 A 而线程 A 还没有完成对自身的锁定,那么解锁的调用就会丢失并且线程 A 保持锁定状态,这会导致死锁。
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 hereseeking help with my code.
我根据 caf 的建议重新制作了我的程序,但我仍然遇到问题。我已经将我的程序塑造成我所能提供的最好的结构 caf,但我现在什至无法说出导致死锁的原因......我在这里创建了一个新问题,寻求有关我的代码的帮助。
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.
下面是 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);
}
}
回答by asveikau
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.
您可以使用pthread_mutex_trylock. 如果成功,则互斥锁无人认领,您现在拥有它(因此您应该释放它并返回“未持有”,在您的情况下)。否则,有人拿着它。
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 tthat the lock is unheld, that says absolutely nothing about whether or not some other thread acquired the lock at t+1.
我必须强调,“检查互斥锁是否无人认领”是一个非常糟糕的主意。这种思维存在固有的竞争条件。如果这样的函数在某个时间告诉您t该锁未持有,则绝对不能说明其他线程是否在 处获得了该锁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...
}
回答by caf
Mutexes are not the right primitive for the scheme that you want to implement. You should be using condition variables:
互斥体不是您要实现的方案的正确原语。您应该使用条件变量:
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);
}
Each thread will block in pthread_cond_wait()until the other thread signals it to wake up. This will not deadlock.
每个线程都会阻塞,pthread_cond_wait()直到另一个线程通知它唤醒。这不会死锁。
It can easily be extended to many threads, by allocating one int, pthread_cond_tand pthread_mutex_tper thread.
通过为每个线程分配一个int,pthread_cond_t和pthread_mutex_t每个线程,它可以轻松扩展到多个线程。
回答by Huang F. Lei
You can't compare a pthread_mutex_t with a int.
您无法将 pthread_mutex_t 与 int 进行比较。
You can use
您可以使用
int pthread_mutex_trylock(pthread_mutex_t *mutex);
to check that.
检查那个。

