简单的生产者-消费者模式

#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <unistd.h>
#include <vector>
//实现了一个有界缓冲区(Bounded Buffer)的生产者-消费者模型。
/*主函数创建了一个大小为 10 的有界缓冲区 bb。
创建一个生产者线程和三个消费者线程。
生产者线程在循环中生产数据,消费者线程从缓冲区中消费数据,直到生产者生产完所有数据,并且所有消费者线程都消费完数据。
这个模型通过互斥量和条件变量实现了线程之间的同步与通信,确保生产者不会在缓冲区满时继续生产,消费者不会在缓冲区空时继续消费,从而保证了线程安全的操作。*/
using namespace std;

const int MAX_NUM =10000;

class BoundedBuffer{
    public:
    //初始化缓冲区的大小为 n,并设置相关成员变量。
    BoundedBuffer(size_t n){
        array_.resize(n);
        start_pos_=0;
        end_pos_=0;
        pos_=0;
    }
    //生产者将整数 n 放入缓冲区
    void Produce(int n){
        {
        //对互斥量 mtx_ 上锁,保护共享资源。
        std::unique_lock<std::mutex> lock(mtx_);
        //条件变量 not_full_ 等待,直到缓冲区不满。
        not_full_.wait(lock,[=]{ return pos_ < array_.size();});

        usleep(1000 * 400); 
        //将数据 n 放入缓冲区,并更新 end_pos_。
        array_[end_pos_]= n;
        end_pos_=(end_pos_+1) %array_.size();
        // 增加 pos_ 计数,并输出当前缓冲区中的位置信息。
        ++pos_;
        cout<<"Produce pos:" <<pos_ <<endl;
    }
    //解锁互斥量后,使用 not_empty_.notify_one(); 通知消费者缓冲区非空。
        not_empty_.notify_one();
    }


    //消费者从缓冲区中取出数据。
    int Consume(){
        // 对互斥量 mtx_ 上锁。
        std::unique_lock<std::mutex> lock(mtx_);
        //条件变量 not_empty_ 等待,直到缓冲区不空。
        not_empty_.wait(lock,[=]{return pos_ > 0 ;});

        usleep(1000*400);
        // 从缓冲区取出数据,并更新 start_pos_。
        int n = array_[start_pos_];
        start_pos_ = (start_pos_ +1) %array_.size();
        //减少 pos_ 计数,并输出当前缓冲区中的位置信息。
        --pos_;
        cout<< "Consume pos:" <<pos_ <<endl;
        lock.unlock();
        //解锁互斥量后,使用 not_full_.notify_one(); 通知生产者缓冲区不满。
        not_full_.notify_one();

        return n;
    }

    private:
    //存储实际的数据元素。其大小由构造函数初始化时设定的 n 决定,表示缓冲区的容量。在这里,array_ 是一个整数类型的向量,用于存储生产者生产的数据和消费者消费的数据。
    std::vector<int> array_;
    //记录缓冲区中起始位置的索引。生产者将数据放入缓冲区时,从 start_pos_ 指示的位置开始放置数据。
    size_t start_pos_;
    //记录缓冲区中结束位置的索引。生产者将数据放入缓冲区时,放置数据后更新 end_pos_,表示新数据的位置。
    size_t end_pos_;
    //记录当前缓冲区中的有效元素个数。这个变量在生产者生产数据和消费者消费数据时被更新,以确保缓冲区中数据的正确管理。
    size_t pos_;
    std::mutex mtx_;
    std::condition_variable not_full_;
    std::condition_variable not_empty_;
};
// // 创建一个大小为 10 的有界缓冲区对象
BoundedBuffer bb(10);

std::mutex g_mtx;


/*Producer() 函数:
生产者线程函数,不断地生产数据,直到生产完100个数据。
调用 bb.Produce(n) 将数据 n 放入缓冲区。
输出生产者生产的数据 n。
当生产完100个数据后,调用 bb.Produce(-1) 表示生产结束。*/
void Producer(){
    int n =0;
    while(n<100){
        // 生产者生产数据 n
        bb.Produce(n);
        cout << "Producer:" << n <<endl;
        n++;
    }
    // 生产结束的标志
    bb.Produce(-1);
}

/*Consumer() 函数:
消费者线程函数,从缓冲区中消费数据。
使用 std::this_thread::get_id() 获取当前线程的 ID。
循环调用 bb.Consume() 消费数据,并输出消费者线程 ID 和消费的数据 n。
当消费到结束标志 -1 时,调用 bb.Produce(-1) 表示消费结束。*/
void Consumer(){
    std::thread::id thread_id = std::this_thread::get_id();
    int n =0;
    do{
         消费者消费数据
        n=bb.Consume();
        cout << "Consumer thread:" <<thread_id <<" =====>" <<n <<endl;

    }while(-1 !=n);
    bb.Produce(-1);
}

/*创建一个存储线程对象的向量 t。
使用 std::thread(&Producer) 创建一个生产者线程,并加入到向量 t 中。
使用 std::thread(&Consumer) 创建三个消费者线程,并分别加入到向量 t 中。
使用 one.join() 等待所有线程执行结束。
返回 0 表示程序正常结束。*/

int main(){
    std::vector<std::thread> t;
    t.push_back(std::thread(&Producer));// 创建生产者线程
    t.push_back(std::thread(&Consumer));// 创建消费者线程
    t.push_back(std::thread(&Consumer));
    t.push_back(std::thread(&Consumer));

    for(auto &one :t){
        one.join();// 等待所有线程结束
  
    }

    return 0;
}


/*输出:
*Produce pos:18446744073709551615
Producer:0
Consume pos:18446744073709551614
Consumer thread:4 =====>0
Consume pos:18446744073709551613
Consumer thread:5 =====>0
Consume pos:18446744073709551612
Consumer thread:3 =====>0
Consume pos:18446744073709551611
Consumer thread:4 =====>0
Consume pos:18446744073709551610
Consumer thread:5 =====>0
Consume pos:18446744073709551609
Consumer thread:3 =====>0
Consume pos:18446744073709551608
Consumer thread:4 =====>0
Consume pos:18446744073709551607
Consumer thread:5 =====>0
Consume pos:18446744073709551606
Consumer thread:3 =====>0
Consume pos:18446744073709551605
Consumer thread:4 =====>0
Consume pos:18446744073709551604
Consumer thread:5 =====>0
Consume pos:18446744073709551603
Consumer thread:3 =====>0
Consume pos:18446744073709551602
Consumer thread:4 =====>0
Consume pos:18446744073709551601
Consumer thread:5 =====>0
**/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值