在发出等待条件变量信号后,当线程获得锁定时?是什么决定了它?

时间:2015-03-03 20:01:43

标签: c++ pthreads condition-variable

在网上搜索,并在stackoverflow上阅读问题答案后,我无法找到问题的答案。

在线程B中调用wait,它解锁互斥锁,允许其他人访问条件变量(用于信令)。然后,当在线程A中发出条件变量信号时,线程B醒来,线程B再次锁定互斥锁。

当线程A通过发信号通知条件变量唤醒线程B时,线程B被唤醒,锁定互斥锁。

我从教程中了解到,每当线程B发出信号时,它都会立即锁定互斥锁。然而,这些示例与此相反,当线程B发出信号并且唤醒时,线程A继续执行,稍后线程B锁定互斥锁。

我的问题是线程B(以下示例中的消费者)何时锁定互斥锁?就在线程B接收信号的那一刻?或者它取决于线程调度程序?

我没有找到任何解释。

我正在考虑以下示例的情况:

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

pthread_mutex_t mutex;
pthread_cond_t cond;

int buffer[100];

int loops = 5;
int length = 0;

void *producer(void *arg) {
    int i,j;
    for (i = 0; i < loops; i++) {
    pthread_mutex_lock(&mutex);
    buffer[length++] = i;
    printf("producer length %d\n", length);
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    }
}

void *consumer(void *arg) {
    int i;
    for (i = 0; i < loops; i++) {
    pthread_mutex_lock(&mutex);
    while(length == 0) {
        printf(" consumer waiting...\n");
        pthread_cond_wait(&cond, &mutex);
    }
    int item = buffer[--length];
    printf("Consumer %d\n", item);
    pthread_mutex_unlock(&mutex);
    }
}

int main(int argc, char *argv[])
{

    pthread_mutex_init(&mutex, 0);
    pthread_cond_init(&cond, 0);

    pthread_t pThread, cThread;
    pthread_create(&pThread, 0, producer, 0);
    pthread_create(&cThread, 0, consumer, 0);
    pthread_join(pThread, NULL);
    pthread_join(cThread, NULL);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

输出:

consumer waiting...
producer length 1
producer length 2
producer length 3
producer length 4
producer length 5
Consumer 4
Consumer 3
Consumer 2
Consumer 1
Consumer 0

提前谢谢

3 个答案:

答案 0 :(得分:4)

条件变量的行为是释放锁并等待(原子地)然后在发出线程信号时重新获取锁的行为。在你的代码中,一个线程在持有互斥锁的同时向另一个线程发出信号,这意味着唤醒线程将进入互斥锁中的等待队列,直到另一个线程释放互斥锁。

答案 1 :(得分:0)

线程B(使用者)使用已获取的互斥锁唤醒,假设pthread_cond_unlock成功返回。因此,您需要检查返回值(即0 =成功)以了解是否已获取互斥锁。

答案 2 :(得分:-1)

在使用pthread条件变量+互斥量时,我只想在这里添加关于不太明显的隐含行为的两分钱。考虑以下顺序:

pthread_mutex_lock(&m);
pthread_con_wait(&cond,&m);
pthread_mutex_unlock(&m);

一旦线程等待'cond',它也会自动解锁互斥锁!!这并不明显,并引起了很多困惑。