C++ 消费者和生产者

//Consume1Producer1
#include "iostream"
#include <thread>
#include <mutex>
#include <condition_variable>
#include <unistd.h>



using namespace std;

static const int itemRepositorySize = 10;
static const int itemToProduce = 50;

struct ItemReposity{
    int itemBuffer[itemRepositorySize];
    size_t readPosition;
    size_t writePosition;
    mutex mtx;
    condition_variable repoNotFull;
    condition_variable repoNotEmpty;
}gItemReposity;

//ItemReposity gItemReposity;
//typedef struct ItemRepository ItemRepository;

void produceItem(ItemReposity* ir, int item)
{
    std::unique_lock<std::mutex> lck(ir->mtx);

    //now produde is full, need consume take it 
    while(((ir->writePosition + 1) % itemRepositorySize) == ir->readPosition)
    {
        cout << "生产的地方满了..." <<endl;
        (ir->repoNotFull).wait(lck);
    }
    (ir->itemBuffer)[ir->writePosition] = item;
    (ir->writePosition)++;

    if(ir->writePosition == itemRepositorySize)
    {
        ir->writePosition = 0;
    }

    (ir->repoNotEmpty).notify_all();
    lck.unlock();
}


int consumeItem(ItemReposity* ir)
{
    int data;
    std::unique_lock<std::mutex> lck(ir->mtx);

    //consume is empty ,need produce 
    while(ir->writePosition == ir->readPosition)
    {
        cout << "已经消费完了,请生产..." <<endl;
        (ir->repoNotEmpty).wait(lck);
    }
    data = (ir->itemBuffer)[ir->readPosition];
    (ir->readPosition)++;

    if(ir->readPosition == itemRepositorySize)
    {
        ir->readPosition = 0;
    }

    (ir->repoNotFull).notify_all();
    lck.unlock();

    return data;
}

void ProducerTask() // 生产者任务
{
    for (int i = 1; i <= itemToProduce; ++i) {
        sleep(1);
        std::cout << "正在生产第 " << i << "个 产品..." << std::endl;
        produceItem(&gItemReposity, i); // 循环生产 kItemsToProduce 个产品.
    }
}

void ConsumerTask() // 消费者任务
{
    static int cnt = 0;
    while(1) {
        //sleep(1);
        int item = consumeItem(&gItemReposity); // 消费一个产品.
        std::cout << "正在消费第 " << item << "个产品" << std::endl;
        if (++cnt == itemToProduce) break; // 如果产品消费个数为 kItemsToProduce, 则退出.
    }
}

void InitItemRepository(ItemReposity *ir)
{
    ir->writePosition = 0; // 初始化产品写入位置.
    ir->readPosition = 0; // 初始化产品读取位置.
}

int main()
{
    InitItemRepository(&gItemReposity);
    std::thread producer(ProducerTask); // 创建生产者线程.
    std::thread consumer(ConsumerTask); // 创建消费之线程.
    producer.join();
    consumer.join();
    

    return 0;
}
//Consume4Producer1
#include <unistd.h>

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

static const int kItemRepositorySize  = 4; // Item buffer size.
static const int kItemsToProduce  = 10;   // How many items we plan to produce.

struct ItemRepository {
    int item_buffer[kItemRepositorySize];
    size_t read_position;
    size_t write_position;
    size_t item_counter;
    std::mutex mtx;
    std::mutex item_counter_mtx;
    std::condition_variable repo_not_full;
    std::condition_variable repo_not_empty;
} gItemRepository;

typedef struct ItemRepository ItemRepository;


void ProduceItem(ItemRepository *ir, int item)
{
    std::unique_lock<std::mutex> lock(ir->mtx);
    while(((ir->write_position + 1) % kItemRepositorySize)
        == ir->read_position) { // item buffer is full, just wait here.
        std::cout << "Producer is waiting for an empty slot...\n";
        (ir->repo_not_full).wait(lock);
    }

    (ir->item_buffer)[ir->write_position] = item;
    (ir->write_position)++;

    if (ir->write_position == kItemRepositorySize)
        ir->write_position = 0;

    (ir->repo_not_empty).notify_all();
    lock.unlock();
}

int ConsumeItem(ItemRepository *ir)
{
    int data;
    std::unique_lock<std::mutex> lock(ir->mtx);
    // item buffer is empty, just wait here.
    while(ir->write_position == ir->read_position) {
        std::cout << "Consumer is waiting for items...\n";
        (ir->repo_not_empty).wait(lock);
    }

    data = (ir->item_buffer)[ir->read_position];
    (ir->read_position)++;

    if (ir->read_position >= kItemRepositorySize)
        ir->read_position = 0;

    (ir->repo_not_full).notify_all();
    lock.unlock();

    return data;
}

void ProducerTask()
{
    bool ready_to_exit = false;
    while(1) {
        sleep(1);
        std::unique_lock<std::mutex> lock(gItemRepository.item_counter_mtx);
        if (gItemRepository.item_counter < kItemsToProduce) {
            ++(gItemRepository.item_counter);
            ProduceItem(&gItemRepository, gItemRepository.item_counter);
            std::cout << "Producer thread " << std::this_thread::get_id()
                << " is producing the " << gItemRepository.item_counter
                << "^th item" << std::endl;
        } else ready_to_exit = true;
        lock.unlock();
        if (ready_to_exit == true) break;
    }
    std::cout << "Producer thread " << std::this_thread::get_id()
                << " is exiting..." << std::endl;
}

void ConsumerTask()
{
    static int item_consumed = 0;
    while(1) {
        sleep(1);
        ++item_consumed;
        if (item_consumed <= kItemsToProduce) {
            int item = ConsumeItem(&gItemRepository);
            std::cout << "Consumer thread " << std::this_thread::get_id()
                << " is consuming the " << item << "^th item" << std::endl;
        } else break;
    }
    std::cout << "Consumer thread " << std::this_thread::get_id()
                << " is exiting..." << std::endl;
}

void InitItemRepository(ItemRepository *ir)
{
    ir->write_position = 0;
    ir->read_position = 0;
    ir->item_counter = 0;
}

int main()
{
    InitItemRepository(&gItemRepository);
    std::thread producer1(ProducerTask);
    std::thread producer2(ProducerTask);
    std::thread producer3(ProducerTask);
    std::thread producer4(ProducerTask);
    std::thread consumer(ConsumerTask);

    producer1.join();
    producer2.join();
    producer3.join();
    producer4.join();
    consumer.join();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值