c - C语言三线程通信问题(发生死锁)
问题描述
我正在创建一个程序,其中我有 3 个链表,并且我试图在这三个线程中从这些链表中更新或删除节点。但是僵局正在发生
插入和删除工作正常。这里三个变量 var1InUse、var2InUse 和 var3InUse 表示这 3 个链表是否在使用中(并非所有三个链表都在所有线程中使用)。正如您在代码中看到的那样,我正在等待基于 var1InUse、var2InUse 和 var3InUse 的线程。有时这可以正常工作,但有时会发生死锁。我已经在互联网上搜索了解决方案,但可以找到它。我是否正确使用了等待和信号方法?
pthread variables declaration
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t t1cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t t2cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t t3cond = PTHREAD_COND_INITIALIZER;
int var1InUse=0,var2InUse=0,var3InUse=0;
线程 1
void* thread1(void* args){
while(var1InUse || var2InUse ) {
pthread_cond_wait(&t1cond,&myMutex);}
var1InUse=1,var2InUse=1;
while(1){
pthread_mutex_lock(&myMutex);
/*
some other code about adding and removing from
linkedlist
*/
var1InUse=0,var2InUse=0;
pthread_cond_signal(&t2cond);
pthread_cond_signal(&t3cond);
pthread_mutex_unlock(&myMutex);}
}
线程 2
void* thread2(void* args){
while(var1InUse || var2InUse || var3InUse) {
pthread_cond_wait(&t2cond,&myMutex);}
var1InUse=1,var2InUse=1,var3InUse=1;
while(1){
pthread_mutex_lock(&myMutex);
/*
some other code adding and removing from linkedlist
*/
var1InUse=0,var2InUse=0,var3InUse=0;
pthread_cond_signal(&t1cond);
pthread_cond_signal(&t3cond);
pthread_mutex_unlock(&myMutex);}
}
线程 3
void* thread3(void* args){
while(var1InUse || var3InUse ) {
pthread_cond_wait(&t3cond,&myMutex);}
var1InUse=1,var3InUse=1;
while(1){
pthread_mutex_lock(&myMutex);
/*
some other code adding and removing from linkedlist
*/
var1InUse=0,var3InUse=0;
pthread_cond_signal(&t1cond);
pthread_cond_signal(&t2cond);
pthread_mutex_unlock(&myMutex);}
}
主要方法
int main(){
pthread_t t1,t2,t3,t4;
pthread_mutex_init(&myMutex,0);
pthread_create(&t1,NULL,thread1,NULL);
pthread_create(&t2,NULL,thread2,NULL);
pthread_create(&t3,NULL,thread3,NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
pthread_mutex_destroy(&myMutex);
return 0
}
我希望消除僵局。
解决方案
使用的互斥pthread_cond_wait()
量需要在调用函数之前锁定。这是手册页的摘录:
pthread_cond_timedwait()
andpthread_cond_wait()
函数应阻塞条件变量。应用程序应确保调用这些函数时调用线程锁定互斥锁;否则,将导致错误(对于 PTHREAD_MUTEX_ERRORCHECK 和健壮的互斥锁)或未定义的行为(对于其他互斥锁)。
虽然pthread_cond_wait()
在内部解锁了互斥锁,但在函数成功返回之前再次被锁定:
成功返回后,互斥锁将被锁定并归调用线程所有。
此外,您应该访问共享变量var1InUse
,var2InUse
并var3InUse
锁定互斥锁。
thread1()
这是遵循这些规则的修改版本。对其他线程启动例程的修改应该类似:
void* thread1(void* args){
pthread_mutex_lock(&myMutex);
while(var1InUse || var2InUse ) {
pthread_cond_wait(&t1cond,&myMutex);
}
var1InUse=1,var2InUse=1;
pthread_mutex_unlock(&myMutex);
while(1){
pthread_mutex_lock(&myMutex);
/*
some other code about adding and removing from linkedlist
*/
var1InUse=0,var2InUse=0;
pthread_cond_signal(&t2cond);
pthread_cond_signal(&t3cond);
pthread_mutex_unlock(&myMutex);
}
return NULL;
}
(我不完全确定上述内容是否正确,因为从原始代码中并不能完全清楚while(1)
循环应该做什么。)
推荐阅读
- python - Python Visual Studio Code 方括号无法识别
- javascript - 我怎样才能总结和计算百分比(正确)?
- java - 从网站读取文件并将它们加载到对象中而不下载文件
- python - pydantic 与 mypy 的使用
- javascript - MongoDB 计数未返回正确的数字
- outlook - 如何在 Windows 机器上查看 Outlook 365 的整个 SMTP 包?
- ios - 如何将 NSString 转换为 UTF-8 以外的编码?
- c++ - 通过 neo4j_client 库删除节点不起作用
- android - 如何在nativescript vue中处理webview上的android后退按钮
- html - 具有 3 个 div 的容器,使用 Flex-box/Grid