zoukankan      html  css  js  c++  java
  • 〔OS〕多线程模拟实现生产者和消费者

    C++ thread 模拟实现的生产者消费者实验。

    /**多生产者多消费者**/
    /**by Darius**/
    #include <bits/stdc++.h>
    using namespace std;
    
    const int MaxSize = 4; //仓库大小
    const int Plan = 100; //计划生产的产品个数
    
    struct WareHouse
    {
        int Q[MaxSize]; //缓冲队列
        int Front, Rear, cnt_ped, cnt_ced; //队头、队尾、已经生产的数量、已经消费的数量
    
        mutex Mutex, P_mutex, C_mutex; //生产者消费者之间的互斥、生产者之间的互斥、消费者之间的互斥
    
        condition_variable Not_full; //生产者条件变量
        condition_variable Not_empty; //消费者条件变量
    
        vector<int> Ready; //准备生产的所有产品的序列
    
        WareHouse() //生成函数
        {
            memset(Q, 0, sizeof Q); //初始化缓冲队列
            cnt_ced = cnt_ped = Front = Rear = 0;
            for (int i = 0; i < Plan; ++i) Ready.push_back(i + 1); //初始化产品序列
        }
    };
    
    static void Producer(WareHouse& Ware_house, int product)
    {
        unique_lock<mutex> lock(Ware_house.Mutex);
        
        while ((Ware_house.Rear + 1) % MaxSize == Ware_house.Front) //判断队列是否满了,满了需要等待
        {
            cout << "Warehouse is full, thread " << this_thread::get_id() << " is waiting.
    ";
            Ware_house.Not_full.wait(lock); //等待不满的条件
        }
        
        Ware_house.Q[Ware_house.Rear++] = product; //生产产品
        Ware_house.Rear %= MaxSize;
    
        cout << "Thread " << this_thread::get_id() << " produced " << product << ", ";
        cout << "the count of products : " << (Ware_house.Rear-Ware_house.Front+MaxSize)%MaxSize << endl;
        
        Ware_house.Not_empty.notify_all(); //因为生产了产品,所有队列非空,通知所有消费者
    }
    
    static void Consumer(WareHouse& Ware_house)
    {
        unique_lock<mutex> lock(Ware_house.Mutex);
        
        while (Ware_house.Front == Ware_house.Rear) //判断队列是否为空,空了需要等待
        {
            cout << "Warehouse is empty, thread " << this_thread::get_id() << " is waiting.
    ";
            Ware_house.Not_empty.wait(lock); //等待非空的条件
        }
        
        int product = Ware_house.Q[Ware_house.Front++]; //消费产品
        Ware_house.Front %= MaxSize;
    
        cout << "Thread " << this_thread::get_id() << " consumed " << product << ", ";
        cout << "the count of products : " << (Ware_house.Rear-Ware_house.Front+MaxSize)%MaxSize << endl;
        
        Ware_house.Not_full.notify_all(); //因为消费了产品,所有队列不满,通知所有生产者
    }
    
    int unit_time_P, unit_time_C; //生产者生产单位时间和消费者消费单位时间
    
    static void Run_P(WareHouse& Ware_house)
    {
        while (true)
        {
            unique_lock<mutex> lock(Ware_house.P_mutex); //生产者之间的互斥,维护所有生产者生产产品的数量
    
            if (Ware_house.cnt_ped >= Plan) break; //生产完所有产品,任务完成,跳出循环
    
            Producer(Ware_house, Ware_house.Ready[Ware_house.cnt_ped]);
            ++Ware_house.cnt_ped;
    
            this_thread::sleep_for(chrono::milliseconds(unit_time_P));
        }
    }
    
    static void Run_C(WareHouse& Ware_house)
    {
        while (true)
        {
            unique_lock<mutex> lock(Ware_house.C_mutex); //消费者之间的互斥,维护所有消费者消费产品的数量
    
            if (Ware_house.cnt_ced >= Plan) break; //消费完所有产品,任务完成,跳出循环
    
            ++Ware_house.cnt_ced;
            Consumer(Ware_house);
    
            this_thread::sleep_for(chrono::milliseconds(unit_time_C));
        }
    }
    
    int main()
    {
        cout << "Thread " << this_thread::get_id() << " is MainFunction." <<endl;
        cout << "请输入生产者生产单位时间(ms): ";
        cin >> unit_time_P;
        cout << "请输入消费者消费单位时间(ms): ";
        cin >> unit_time_C;
        WareHouse W_h;
    
        thread p1(Run_P, ref(W_h)); //创建多个生产者进程
        thread p2(Run_P, ref(W_h));
        thread p3(Run_P, ref(W_h));
    
        thread c1(Run_C, ref(W_h)); //创建多个消费者进程
        thread c2(Run_C, ref(W_h));
        thread c3(Run_C, ref(W_h));
    
        p1.join();
        p2.join();
        p3.join();
    
        c1.join();
        c2.join();
        c3.join();
    
        return 0;
    }
    
  • 相关阅读:
    彼之蜜糖,吾之砒霜——聊聊软件开发中的最佳实践
    WebAPI框架里设置异常返回格式统一
    Entity Framework Plus
    实体框架自定义代码优先约定(EF6以后)
    npm 切换淘宝镜像几种方式
    EntityFramework中Json序列化的循环引用问题解决--Newtonsoft.Json
    Json序列化循环引用的问题
    Windows Service 之 安装失败后的删除
    Windows Service 之 详解(二)
    Windows Service 之 详解(一)
  • 原文地址:https://www.cnblogs.com/DariusOrz/p/12931448.html
Copyright © 2011-2022 走看看