ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

进程同步-经典同步问题

2020-05-20 10:55:21  阅读:268  来源: 互联网

标签:std 同步 进程同步 read lock ir write 经典 position


 

 

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

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


//单生产者--单消费者
namespace SS
{
    struct ItemRepository
    {
        // 产品缓冲区, 配合 read_position 和 write_position 模型环形队列.
        int item_buffer[kItemRepositorySize]; 
        // 消费者读取产品位置.
        size_t read_position; 
        // 生产者写入产品位置.
        size_t write_position;
        // 互斥量,保护产品缓冲区(同一时间只能被生产者或消费者使用)
        std::mutex 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)
        { //缓存区满的时候,生产者需要等待缓存区不为满的时候才能继续生成,挂起等待
            {
                std::lock_guard<std::mutex> lock(mutex);
                std::cout << "缓冲区满,等待缓冲区不满\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(); // 通知消费者产品库不为空.
    }

    //消费者
    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::lock_guard<std::mutex> lock(mutex);
                std::cout << "缓冲区空,等待生产者生成产品\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(); // 通知消费者产品库不为满.

        return data; // 返回产品.
    }

    // 生产者任务
    void ProducerTask() 
    {
        for (int i = 1; i <= kItemsToProduce; ++i)
        {
            // sleep(1);
            ProduceItem(&gItemRepository, i); // 循环生产 kItemsToProduce 个产品.

            {
                std::lock_guard<std::mutex> lock(mutex);
                std::cout << "生产第 " << i << "个产品" << std::endl;
            }
        }
    }

    // 消费者任务
    void ConsumerTask() 
    {
        static int cnt = 0;
        while (1)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            int item = ConsumeItem(&gItemRepository); // 消费一个产品.
            {
                std::lock_guard<std::mutex> lock(mutex);
                std::cout << "消费第" << item << "个产品" << std::endl;
            }
            // 如果产品消费个数为 kItemsToProduce, 则退出.
            if (++cnt == kItemsToProduce) break; 
        }
    }

    //初始化开始条件
    void InitItemRepository(ItemRepository *ir)
    {
        ir->write_position = 0; // 初始化产品写入位置.
        ir->read_position = 0; // 初始化产品读取位置.
    }

    void test()
    {
        InitItemRepository(&gItemRepository);

        //新建多个生产者或消费者线程实现多产/多消
        std::thread producer(ProducerTask); // 创建生产者线程.
        std::thread consumer(ConsumerTask); // 创建消费之线程.

        producer.join();
        consumer.join();
        //互斥变量的使用,实现生产者和消费者的循环使用
    }
}

//单生产者-多消费者

int main()
{

    SS::test();
    return 0;
}
单产单消

 

标签:std,同步,进程同步,read,lock,ir,write,经典,position
来源: https://www.cnblogs.com/-citywall123/p/12922269.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有