【C++】互斥锁

避免多个线程同时访问共享资源,避免数据竞争,提供线程间同步。

互斥锁mutex

  • lock()上锁

  • unlock解锁

  • recursive_mutex递归锁:同一个线程可以获取多次锁,不会产生死锁。

锁管理者:

  • lock_guard锁管理者:对象构造时加锁、析构时解锁

  • scoped_lock:用于多个互斥体的免死锁RALL封装器对象构造时加锁、析构时解锁

  • unique_lock:实现可移动的互斥体所有权包装器(可以把锁解锁取下来)

条件变量

        获得锁(资源)若条件不满足:条件变量wait解锁将线程放到条件变量队列中。notify唤醒后加锁放入互斥队列中。

唤醒:

  • notify_one:唤醒一个

  • notify_all:唤醒全部

等待:

  • wait:阻塞当前线程,直到条件变量被唤醒

  • wait_for:指定时长时限后

  • wait_until:指定时间点

wait分四步:

  1. unlock互斥锁

  2. 阻塞当前线程

  3. mut.lock(再次持有锁资源,唤醒线程)

  4. 返回

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
using namespace std;
​
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
​
void work_thread()//线程函数
{
    cout<<"work_thread begin"<<endl;
    std::unique_lock<std::mutex> lock(mtx);//mtx.lock,unique_lock不用自己释放锁资源。
    while(!ready)//ready==false(主线程还没改read)//防止虚假唤醒
    {
        cout<<"ready == flase"<<endl;
        cv.wait(lock);//没有锁(不持有资源)是不能用wait的
        //wait等待被唤醒
    }
    cout<<"work_thread run"<<endl;
    cout<<"work_thread end"<<endl;
}
int main()//主线程
{
    std::thread tha(work_thread);
    
    {
        std::unique_lock<std::mutex> lock(mtx);
        ready = true;
        cout<<"main signals ready"<<endl;
    }
    
    tha.join();//阻塞等待线程返回
    
}

让三个线程分别运行A B C A B C的输出10次。

wait到条件变量队列,互斥锁释放。

条件变量队列:cv,被唤醒后放到mutex互斥队列中。

一个锁释放:互斥队列中的一个线程被唤醒到。必须获取锁才能从wait返回到就绪。

#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
using namespace std;
std::mutex mtx;
std::condition_variable cv;
const int n = 10;
int tag = 1;//1A,2B,3C,1A
​
void funa()
{
    std::unique_lock<std::mutex> lock(mtx);
    for (int i = 0; i < n; ++i)
    {
        while (tag != 1)
        {
            cv.wait(lock);
        }
        printf("funa: A \n");
        tag = 2;
        cv.notify_all();
    }
}
​
void funb()
{
    std::unique_lock<std::mutex> lock(mtx);
    for (int i = 0; i < n; ++i)
    {
        while (tag != 2)
        {
            cv.wait(lock);
        }
        printf("funb: B \n");
        tag = 3;
        cv.notify_all();
        
    }
}
void func()
{
    std::unique_lock<std::mutex> lock(mtx);
    for (int i = 0; i < n; ++i)
    {
        while (tag != 3)
        {
            cv.wait(lock);
        }
        printf("func: C \n");
        tag = 1;
        cv.notify_all();
    }
}
int main()
{
    std::thread tha(funa);
    std::thread thb(funb);
    std::thread thc(func);
    tha.join();
    thb.join();
    thc.join();
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曦樂~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值