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全满。

  • 相关阅读:
    1014 Waiting in Line (30)(30 point(s))
    1013 Battle Over Cities (25)(25 point(s))
    1012 The Best Rank (25)(25 point(s))
    1011 World Cup Betting (20)(20 point(s))
    1010 Radix (25)(25 point(s))
    1009 Product of Polynomials (25)(25 point(s))
    1008 Elevator (20)(20 point(s))
    1007 Maximum Subsequence Sum (25)(25 point(s))
    1006 Sign In and Sign Out (25)(25 point(s))
    1005 Spell It Right (20)(20 point(s))
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/5634202.html
Copyright © 2011-2022 走看看