zoukankan      html  css  js  c++  java
  • C++11实现生产者消费者问题

    生产者消费者问题是多线程并发中一个非常经典的问题。我在这里实现了一个基于C++11的,单生产者单消费者的版本,供大家参考。

    #include <windows.h>
    #include <iostream>
    #include <cstdlib>
    #include <mutex>
    #include <thread>
    #include <condition_variable>
    const int bufferSize=10;
    struct ItemRepository
    {
        int item_buffer[bufferSize];
        int write_pos;  //current position of producer
        int read_pos;   //current position of consumer
        std::condition_variable not_empty_con;
        std::condition_variable not_full_con;
        std::mutex mtx;
    }itemRepository;
    
    void produce_one_item(ItemRepository*ir)
    {
        if (!ir)
            return;
        int* item_buffer = ir->item_buffer;
        std::unique_lock<std::mutex> lock(ir->mtx);
        if (ir->write_pos == ir->read_pos&&
            item_buffer[ir->write_pos] == 1)//the repository is full
        {
            std::cout << "The producer is waiting for an empty." << std::endl;
            ir->not_full_con.wait(lock);
        }
    
        item_buffer[ir->write_pos] = 1;//now the buffer in this position is full
        std::cout << "The producer produces a new item on " << ir->write_pos << std::endl;
        ir->write_pos++;
        ir->not_empty_con.notify_all();//notify the consumer to consume items
    
        if (ir->write_pos == bufferSize)
            ir->write_pos = 0;
    }
    
    void consume_one_item(ItemRepository*ir)
    {
        if (!ir)
            return;
        int* item_buffer = ir->item_buffer;
        std::unique_lock<std::mutex> lock(ir->mtx);
    
        if (ir->read_pos == ir->write_pos&&
            item_buffer[ir->write_pos] == 0)//the repository is empty
        {
            std::cout << "The consumer is waiting for items." << std::endl;
            ir->not_empty_con.wait(lock);
        }
    
        item_buffer[ir->read_pos] = 0;//now the buffer in this position is empty
        std::cout << "The consumer consumes an item on " << ir->read_pos << std::endl;
        ir->read_pos++;
        ir->not_full_con.notify_all();//notify the producer to produce new items
        
        if (ir->read_pos == bufferSize)
            ir->read_pos = 0;
    }
    
    void produceTask()
    {
        for (int i = 0; i < 50; i++)
            produce_one_item(&itemRepository);
    }
    
    void consumeTask()
    {
        for (int i = 0; i < 50; i++)
        {
            Sleep(1);
            consume_one_item(&itemRepository);
        }
    }
    
    void initializeRepository(ItemRepository*ir)
    {
        if (!ir)
            return;
        ir->read_pos = 0;
        ir->write_pos = 0;
    }
    
    int main()
    {
        initializeRepository(&itemRepository);
        std::thread producer(produceTask);
        std::thread consumer(consumeTask);
        producer.join();
        consumer.join();
        system("pause");
        return 0;
    }

    注意我判断item_buffer中的物品是否全空或者全满的条件:生产者和消费者的位置相等时,若该位置上为空则buffer全空,若为满则buffer全满。

  • 相关阅读:
    优化SQL Server数据库的经验总结
    #main和.main区别
    通过SQL把n条记录插入表中
    11月6日到8日参加微软Tech.ED2008大会
    NOIP2017 D2T1奶酪
    NOIP2017 D1T2时间复杂度
    NOIP2017 D2T2宝藏
    NOIP2017 D1T1小凯的疑惑
    NOIP2017 D1T3逛公园
    NOIP2017 D2T3列队
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/5634202.html
Copyright © 2011-2022 走看看