C语言中三个线程的通信出现问题(出现死锁)



我正在创建一个程序,其中有3个链表,我正试图在这三个线程中更新或删除这些链表中的节点。但僵局正在发生

插入和删除操作正常。这里的三个变量var1InUse、var2InUse和var3InUse指示3个链表是否在使用中(并非所有三个都在所有线程中使用(。正如您在代码中看到的那样,我基于var1Use、var2Use和var3Use将线程置于等待状态。有时这很好,但有时会发生死锁。我在网上搜索过解决方案,但能找到。我是否正确使用了等待和信号方法?

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()pthread_cond_wait()函数应阻塞条件变量。应用程序应确保在调用线程锁定互斥的情况下调用这些函数;否则,将导致错误(对于PTHREAD_MUTEX_ERRORCHECK和健壮互斥(或未定义的行为(对于其他互斥(。

尽管pthread_cond_wait()在内部解锁互斥锁,但在函数成功返回之前,它会再次被锁定:

成功返回后,互斥锁将被锁定,并归调用线程所有。

此外,您应该在互斥锁被锁定的情况下访问共享变量var1InUsevar2InUsevar3InUse

这是您的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)循环应该做什么。(

最新更新