pthread 和访问临界区

pthread and accessing the critical section

好吧,下面的代码是针对两个线程的。我对互斥体有一些问题。 创建线程 t1 后,它调用 add_queue()。然后它会通知线程 t2 在其临界区工作。但是,程序不会为线程 t2 运行。 线程 t1 的 运行s 并在其临界区执行其工作。然后,我锁定了线程 t2 的互斥量。但是,程序卡在了第 29 行。

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

static int pending_requests =0;
static pthread_mutex_t prmutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t prcondition = PTHREAD_COND_INITIALIZER;

static int critical = 0;

int get_number_requests(void)
{
    return pending_requests;
}

void add_queue()
{
    pthread_mutex_lock(&prmutex);
    pending_requests++;
    critical++;    
    pthread_mutex_unlock(&prmutex);
    printf("xxxx\n");
    printf("critical=%d\n",critical);

}

void remove_from_queue()
{
    pthread_mutex_lock(&prmutex);
    pending_requests--;
    printf("BBBBcritical=%d\n",critical);
    critical--;
    printf("BBBcritical=%d\n",critical);

    pthread_mutex_unlock(&prmutex);

}

void *get_request()
{
    add_queue();
    if (get_number_requests() != 0)
    {    
        printf("I have a element in the queue. Signalling to processor thread..\n");
        pthread_cond_signal(&prcondition);
    }
    pthread_exit(0);
}

void *processor()
{
    while(get_number_requests() == 0)
    {
        printf("BBB This is a processor thread, I am waiting..\n");
        pthread_cond_wait(&prcondition,&prmutex);
    }
    while(get_number_requests() !=0)
    {
        printf("aaaa\n");
        remove_from_queue();
        pthread_cond_signal(&prcondition);
    }

    pthread_exit(0);
}


int main()
{
    pthread_t t1,t2;
    printf("critical=%d\n",critical);
    pthread_create(&t1,NULL,get_request,NULL);
    pthread_create(&t2,NULL,processor,NULL);
    printf("critical=%d\n",critical);

    pthread_join(t1,NULL);
    pthread_join(t2,NULL);
}

您对 pthread_cond_wait 的使用在很多方面都是错误的。仔细阅读 pthread_cond_waitman page 将帮助您了解如何正确使用它。

  1. 在调用 pthread_cond_wait 之前,必须锁定互斥量。来自手册:

    They shall be called with mutex locked by the calling thread or undefined behavior results.

    即调用pthread_cond_wait前需要先调用pthread_mutex_lock

  2. pthread_cond_wait returns 时,它将锁定互斥量。来自手册:

    Upon successful return, the mutex shall have been locked and shall be owned by the calling thread.

    所以在remove_from_queue中再次尝试锁定是错误的。由于互斥锁已经被锁定,remove_from_queue 中的 pthread_mutex_lock 调用将无限期地阻塞,正如您所发现的(即,线程自身已死锁)。