浅析pthread_cond_wait函数

前言

pthread_cond_wait函数是Linux下条件变量的函数之一,这个函数也是其中最为复杂的一个函数,其功能为:只要到这个函数,就发生阻塞,直到使用pthread_cond_signal或者pthread_cond_broadcast给条件变量发送信号,此时该线程才继续运行,其主要用三个功能:

  1. 阻塞等待条件变量cond

  2. 释放已掌握的互斥锁(解锁互斥量)相当于ptherad_mutex_unlock(&mutex);

    1、2两步为一个原子操作

  3. 当被唤醒,pthread_cond_wait函数返回时,解除阻塞并重新申请获取互斥锁pthread_mutex_lock(&mutex);

总结一下,运行到这里就会发生阻塞与此同时开始放锁,这个两个是原子操作,同时发生。有信号发过来,函数执行完毕,重新加锁。下面结合代码讲解一下,参考自https://www.cnblogs.com/god-of-death/p/11452308.html.:

代码示例

#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
pthread_t tid[3];
int sum = 0;
pthread_mutex_t sumlock = PTHREAD_MUTEX_INITIALIZER; /* 静态初始化互斥量 */
pthread_cond_t cond_sum_ready = PTHREAD_COND_INITIALIZER; /* 静态初始化条件变量 */
void * t1t2(void *arg) {
    int i;
    long id = (long)arg;
    for (i = 0; i < 60; i++) {
        pthread_mutex_lock(&sumlock); /* 使用互斥量保护临界变量 */
        sum++;
        printf("t%ld: read sum value = %d\n", id + 1 , sum);
        pthread_mutex_unlock(&sumlock);
        if (sum >= 100)
        pthread_cond_signal(&cond_sum_ready); /* 发送条件通知,唤醒等待线程 */
}
    return NULL;
}
void * t3(void *arg) {
    pthread_mutex_lock(&sumlock);
    while(sum < 100 ) /* 不满足条件将一直等待 */
    {
        printf("Waiting the signal...\n");
        pthread_cond_wait(&cond_sum_ready, &sumlock); /* 等待条件满足 */
    }

    sum = 0;
    printf("t3: clear sum value\n");
    pthread_mutex_unlock(&sumlock);
    return NULL;
}
int main(void) {
    int err;
    long i;
    for (i = 0; i < 2; i++) {
        err = pthread_create(&(tid[i]), NULL, &t1t2, (void *)i); /* 创建线程 1 线程 2 */
        if (err != 0) {
        printf("Can't create thread :[%s]", strerror(err));
} }
    err = pthread_create(&(tid[2]), NULL, &t3, NULL); /* 创建线程 3 */
    if (err != 0)
        printf("Can't create thread :[%s]", strerror(err));
    for (i = 0; i < 3; i++)
        pthread_join(tid[i], NULL);
    return 0;
}

在上面这段代码中,我们先创建了三个线程,前两个线程对sum进行自增运算,由于使用了互斥锁,整个操作是安全的。第三个线程开始执行,为防止竞争,依旧加锁, 此时,sum还没加到100, 进入while循环体,打印“Waiting the signal…”后,开始执行pthread_cond_wait函数,于是就发生了上述的1、2步,线程3阻塞并放锁,线程1或线程2拿到锁继续执行,sum终于到了101,两个线程中一个开始发送信号,线程3开始执行,pthread_cond_wait函数执行完毕,结果此时sum的值已经大于100了,于是while循环结束,继续执行下面的操作。

要点

其实还是上面那3点,一定要结合代码实际进行记忆

  1. “Waiting the signal…”仅仅输出了一次,说明整个运行是阻塞的;
  2. sum增加到了100,说明这个互斥锁已经释放了,不然就会发生死锁;
  3. pthread_cond_wait函数返回时,还会重新加锁,不然此时就会产生竞争;
  4. sum肯定只会从1加到101,因此pthread_cond_wait一定先于pthread_cond_signal运行,二者的顺序必须保证,不然会一直阻塞!
  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值