第十课:C++多线程生产者消费模式

本文展示了一个C++实现的生产者消费者模式例子,使用了多线程、互斥量和条件变量来控制仓库的生产和消费操作。生产者线程生成产品并放入仓库,消费者线程则从仓库取出产品进行消费。仓库容量有限,当仓库满时生产者会等待,当仓库空时消费者会等待。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码案例中有注解,这里就不过过多解释了。直接看案例代码吧!

#include<condition_variable>
#include<mutex>
#include<thread>
#include<iostream>
#include<chrono>

using namespace std;
using namespace this_thread;

//C++多线程生产者消费模式(案例)
const int kProduceTtems = 20;    //产品个数
const int kPepositorySize = 5;   //仓库大小

//仓库类
template<class T>

class Repository
{
public:

    deque<T> items_buff;     //存储产品
    mutex mtx;               //生产者和消费者的互斥量
    mutex produce_mutex;     //生产计数互斥量
    mutex consume_mutex;     //消费计数互斥量

    condition_variable repo_not_full;  //仓库不满状态条件变量
    condition_variable repo_ont_empty; //仓库不空状态条件

    size_t produce_item_count;
    size_t consume_item_count;

    size_t produce_position;
    size_t consume_position;
     

    Repository()
    {
        produce_item_count = 0;
        consume_item_count = 0;

        produce_position = 0;
        consume_position = 0;
    }


};

//工厂类
template <class T>

class Factory
{
protected:

    Repository<T> repo;
    //产品放到仓库
    void ProduceItme(Repository<T> &repo,T item)
    {
        unique_lock<mutex> lock(repo.mtx);   //加锁

        repo.items_buff.push_back(item);

        if (repo.produce_position == kPepositorySize)
        {
            repo.consume_item_count = 0;
        }
        repo.repo_ont_empty.notify_all();
        lock.unlock();
    }
    //从仓库取产品
    T ConsumeItem(Repository<T> & repo)
    {
        unique_lock<mutex> lock(repo.mtx);

        while (repo.items_buff.empty())
        {
            cout << "无货源,等待......" << endl;

            repo.repo_ont_empty.wait(lock);
        }
        T date = repo.items_buff.front();

        repo.items_buff.pop_front();

        if (repo.consume_item_count == kPepositorySize)
        {
            repo.consume_item_count = 0;
        }

        repo.repo_not_full.notify_all();
        lock.unlock();
        return date;

     }

public:
    //生产者操作
    void ProduceTask()
    {
        bool ready_to_exit = false;

        while (true)
        {
            unique_lock<mutex> lock(repo.produce_mutex);
            //线程结束条件
            if (repo.produce_item_count < kProduceTtems)
            {
                repo.produce_item_count++;

                //生产产品的代码块
                this_thread::sleep_for(1s);
                T item = repo.produce_item_count;
                cout << "生产者ID:" << this_thread::get_id() << "货编号:[" << item << "]" << endl;
                ProduceItme(repo, item);
            }
            else
            {
                ready_to_exit = true;
            }
            lock.unlock();

            if (ready_to_exit)
            {
                break;
            }
        }
    }
    //消费者操作
    void ConsumeTask()
    {
        bool read_to_exit = false;
        while (true)
        {
            unique_lock<mutex> lock(repo.consume_mutex);

            if (repo.consume_item_count < kProduceTtems)
            {
                T item = ConsumeItem(repo);

                //消费产品代码块
                this_thread::sleep_for(1s);
                cout << "消费者ID:" << this_thread::get_id() << "货源编号:[" << item << "]" << endl;
                repo.consume_item_count++;

            }
            else
            {
                read_to_exit = true;
            }
            lock.unlock();

            if (read_to_exit)
            {
                break;
            }
        }
    }

};


int main()
{
    cout << "主线程ID:"<<this_thread::get_id() << endl;

    Factory<int> myFactory;

    thread produce1(&Factory<int>::ProduceTask, &myFactory);
    thread produce2(&Factory<int>::ProduceTask, &myFactory);
    thread produce3(&Factory<int>::ProduceTask, &myFactory);

    thread consumer1(&Factory<int>::ConsumeTask, &myFactory);
    thread consumer2(&Factory<int>::ConsumeTask, &myFactory);
    thread consumer3(&Factory<int>::ConsumeTask, &myFactory);

    produce1.join();
    produce2.join();
    produce3.join();

    consumer1.join();
    consumer2.join();
    consumer3.join();


    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值