〔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.\n";
        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.\n";
        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;
}

原文链接: https://www.cnblogs.com/darius-link/p/12931448.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    〔OS〕多线程模拟实现生产者和消费者

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/350060

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午6:04
下一篇 2023年3月2日 上午6:04

相关推荐