C++实现 线程互斥 和 线程通信(实战)

线程互斥

多线程环境中运行的代码段我们需要考虑竞态条件,如果存在竞态条件,那这段代码就需要进行互斥来避免竞态产生。

mutex

举个例子
三个窗口一起卖100张票,各个窗口对于临界资源tickets需要互斥访问

#include <iostream>
using namespace std;
#include <string>
#include <mutex>
#include <thread>

volatile int tickets = 100;
mutex mtx;

void sellTickets(string name)
{
    while (tickets > 0)
    {
        mtx.lock();
        if (tickets > 0)
        {
            cout << name << "售出第" << tickets << "张票" << endl;
            tickets--;
        }
        mtx.unlock();
        this_thread::sleep_for(chrono::milliseconds(100));
    }
}

int main()
{
    thread t1(sellTickets, "一窗口");
    thread t2(sellTickets, "二窗口");
    thread t3(sellTickets, "三窗口");

    t1.join();
    t2.join();
    t3.join();

    return 0;
}

运行结果:
在这里插入图片描述

学习使用基于CAS的原子类型

开10个线程并发给count++,每个线程增加1000次


atomic_int count(0);
void sell()
{
    //每个线程给count加1000次
    for (int i = 0; i < 1000; i++)
    {
        count++;
    }
}

int main()
{
    vector<thread> vec;
    for (int i = 0; i < 10; i++)
    {
        vec.push_back(thread(sell));
    }

    for (int i = 0; i < 10; i++)
    {
        vec[i].join();
    }

    cout << "Count : " << count << endl;
}

输出结果每次都是1000

https://blog.csdn.net/QIANGWEIYUAN/article/details/88792621

线程同步通信

条件变量condition_variable

生产者消费者模型

#include <iostream>
#include <vector>
using namespace std;
#include <string>
#include <mutex>
#include <thread>
#include <atomic>
#include <condition_variable>

//条件变量要和互斥锁一起使用
mutex mtx;
//条件变量,线程间通信
condition_variable cv;
//定义vector容器,作为生产者消费者共享容器
vector<int> vec;
void producer()
{
    //每生产一个就通知消费者消费一个
    for (int i = 0; i < 10; i++)
    {
        //获取mtx互斥锁资源
        unique_lock<mutex> lock(mtx);

        //容器不为空,还有产品没消费,等待消费完再生产
        while (!vec.empty())
        {
            cv.wait(lock);
        }

        //可以生产啦
        vec.push_back(i);
        cout << "producer生产产品:" << i << endl;

        //通知去消费
        cv.notify_all();
    }
}

void comsumer()
{
    for (int i = 0; i < 10; i++)
    {
        //获取互斥资源
        unique_lock<mutex> lock(mtx);
        //空,那就等会
        while (vec.empty())
        {
            cv.wait(lock);
        }
        int data = vec.back();
        vec.pop_back();
        cout << "生产者消费产品:" << data << endl;

        //通知生产
        cv.notify_all();
    }
}

int main()
{
    thread t1(producer);
    thread t2(comsumer);

    t1.join();
    t2.join();

    return 0;
}

在这里插入图片描述

轮流打印abc


mutex mtx;
condition_variable cv;
int ready = 0;
void PrintString_1()
{
    unique_lock<mutex> lock(mtx);
    //打印十次
    for (int i = 0; i < 10; i++)
    {
        //不等于0就等等
        while (ready != 0)
        {
            cv.wait(lock);
        }
        cout << this_thread::get_id() << ": A" << endl;
        ready = 1;
        cv.notify_all();
    }
}
void PrintString_2()
{
    unique_lock<mutex> lock(mtx);
    //打印十次
    for (int i = 0; i < 10; i++)
    {
        //不等于1就等等
        while (ready != 1)
        {
            cv.wait(lock);
        }
        cout << this_thread::get_id() << ": B" << endl;
        ready = 2;
        cv.notify_all();
    }
}
void PrintString_3()
{
    unique_lock<mutex> lock(mtx);
    //打印十次
    for (int i = 0; i < 10; i++)
    {
        //不等于2就等等
        while (ready != 2)
        {
            cv.wait(lock);
        }
        cout << this_thread::get_id() << ": C" << endl;
        ready = 0;
        cv.notify_all();
    }
}
int main()
{
    thread t1(PrintString_1);
    thread t2(PrintString_2);
    thread t3(PrintString_3);
    t1.join();
    t2.join();
    t3.join();

    return 0;
}

输出结果在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值