检查 pthread 互斥体是否被锁定或解锁(线程锁定自身之后)
我需要查看互斥体是否在 if 语句中被锁定或解锁,所以我像这样检查它...
if(mutex[id] != 2){
/* do stuff */
}
但是当我检查它时,gcc 给出了以下错误:
error: invalid operands to binary != (have ' ptherad_mutex_t' 和 'int')
那么我如何检查互斥体是否被锁定?
编辑:
我的问题的一个关键组成部分是我的线程(根据设计)在将控制权传递给另一个线程后立即锁定自己。因此,当线程 A 将控制权传递给线程 B 时,线程 A 被锁定,线程 B 执行一些操作,然后当线程 B 完成时,它将解锁线程 A。
这样做的问题是,如果线程 B 尝试解锁线程 A 并且线程 A尚未完成锁定本身,则对解锁的调用将丢失,并且线程 A 保持锁定状态,这会导致死锁。
更新:
我根据咖啡馆的建议重新编写了程序,但仍然遇到问题。我已尽我所能将我的程序模制到结构咖啡馆中,但我什至无法说出现在导致死锁的原因...我创建了一个新问题 在这里寻求有关我的代码的帮助。
以下是 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);
}
}
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);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用
pthread_mutex_trylock
。如果成功,则互斥锁未被认领,并且您现在拥有它(因此您应该释放它并返回“未持有”,在您的情况下)。不然就有人拿着了。我必须强调,“检查互斥体是否无人认领”是一个非常糟糕的主意。这种思维存在固有的竞争条件。如果这样的函数在时间
t
告诉您锁未被持有,则绝对没有说明其他线程是否在t+1
获取了锁。如果用代码示例可以更好地说明这一点,请考虑:
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:
对于您想要实现的方案来说,互斥锁不是正确的原语。您应该使用条件变量:
每个线程都会阻塞在
pthread_cond_wait()
中,直到另一个线程发出信号将其唤醒。这样就不会陷入僵局。通过为每个线程分配一个
int
、pthread_cond_t
和pthread_mutex_t
,它可以轻松扩展到多个线程。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.您无法将 pthread_mutex_t 与 int 进行比较。
你可以用
它来检查一下。
You can't compare a pthread_mutex_t with a int.
You can use
to check that.