首页 > 解决方案 > 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
            }

我希望消除僵局。

标签: cmultithreadingpthreadsposixdeadlock

解决方案


使用的互斥pthread_cond_wait()量需要在调用函数之前锁定。这是手册页的摘录:

pthread_cond_timedwait()andpthread_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)循环应该做什么。)


推荐阅读