条件变量为何必须和互斥锁一起使用

在学习操作系统时候,其中关于线程的同步有四种方式:互斥锁,条件变量,读写锁,信号量,互斥锁,读写锁和信号量,这些都比较容易理解,关于条件变量,就不太好理解了,其中条件变量还注明了必须与互斥锁一起使用,接下来就以我的理解来说明一下,条件变量为何需要和互斥锁一起使用。
最好的理解就是从代码出发
首先贴一段最简单的互斥锁与条件变量一起使用的代码:

#include <iostream>
#include <pthread.h>
#include <unistd.h>

using namespace std;
pthread_cond_t qready=PTHREAD_COND_INITIALIZER;   //cond
pthread_mutex_t qlock=PTHREAD_MUTEX_INITIALIZER;  //mutex
int x=10,y=20;
void *f1(void *arg)
{
    cout<<"f1 start"<<endl;
    pthread_mutex_lock(&qlock);
    while(x<y)
    {
        pthread_cond_wait(&qready,&qlock);
    }
    pthread_mutex_unlock(&qlock);
    sleep(3);
    cout<<"f1 end"<<endl;
    return 0;
}
void *f2(void *arg)
{
    cout<<"f2 start"<<endl;
    pthread_mutex_lock(&qlock);
    x=20;
    y=10;
    cout<<"has a change,x="<<x<<" y="<<y<<endl;
    pthread_mutex_unlock(&qlock);
    if(x>y)
    {
        pthread_cond_signal(&qready);
    }
    cout<<"f2 end"<<endl;
    return 0;
}
int main()
{
    pthread_t tids[2];
    int flag;
    flag=pthread_create(&tids[0],NULL,f1,NULL);
    if(flag)
    {
        cout<<"pthread 1 create error "<<endl;
        return flag;
    }
    sleep(2);
    flag=pthread_create(&tids[1],NULL,f2,NULL);
    if(flag)
    {
        cout<<"pthread 2 create erro "<<endl;
        return flag;
    }
    sleep(5);
    return 0;
}

如果不理解pthread_cond_wait这个函数,很难理解整个流程,先看输出结果
在这里插入图片描述

可以看到创建了两个线程,f1线程先执行,接下来,f1线程上锁,等待条件改变,进入阻塞状态,接下来,f2线程开始执行,f2线程上锁,改变了x和y变量,f2线程解锁,如果改变成功,则唤醒f1线程的阻塞,f2线程结束,f1线程解锁,f1线程结束。
这里有个问题:f1线程上锁后,并没有解锁,f2线程是如何拿到锁变量的,这里就需要详细展开 pthread_cond_wait这个函数,这个函数具体做了什么事情:它首先将当前线程加入到唤醒队列,然后旋即解锁mutex,最后等待被唤醒。被唤醒后,又对mutex加锁
我做了一幅图,可以更容易理解:
在这里插入图片描述

所以, pthread_cond_wait在内部将互斥锁已经解开,这也就是为何pthread_cond_wait(&qready,&qlock)里面也把锁变量作为参数,也就回答了为了条件变量为何要和互斥锁一起使用。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值