• 生产者消费者模型


    #include <iostream>
    #include <windows.h>
    #include <time.h>
    using namespace std;
    static const int BUFFERSIZE = 10;
    static const int PRODUCT_NUM = 50;
    HANDLE mutex;
    HANDLE fullSemaphore;
    HANDLE emptySemaphore;
    int real_product_num = 0;
    int curVal = 0;
    void produce()
    {
        if(curVal >= BUFFERSIZE)return;
        cout<<"当前产品数为:"<<curVal<<"  ";
        curVal++;
        cout<<"生产后产品数为:"<<curVal<<endl;
        real_product_num++;
    
    }
    DWORD WINAPI Producer(LPVOID lpPara)
    {
        while(real_product_num < PRODUCT_NUM)
        {
            WaitForSingleObject(fullSemaphore,INFINITE);
            WaitForSingleObject(mutex,INFINITE);
            produce();
            Sleep(80);
            ReleaseMutex(mutex);
            ReleaseSemaphore(emptySemaphore,1,NULL);
        }
    }
    void consume()
    {
        if(curVal <= 0)return;
        cout<<"当前产品数为:"<<curVal<<"  ";
        curVal--;
        cout<<"消费后产品数为:"<<curVal<<endl;
    }
    DWORD WINAPI Consumer(LPVOID lpPara)
    {
        while(real_product_num < PRODUCT_NUM)
        {
            WaitForSingleObject(emptySemaphore,INFINITE);
            WaitForSingleObject(mutex,INFINITE);
            consume();
            Sleep(100);
            ReleaseMutex(mutex);
            ReleaseSemaphore(fullSemaphore,1,NULL);
        }
    }
    int main()
    {
        mutex = CreateMutex(NULL,FALSE,NULL);
        fullSemaphore = CreateSemaphore(NULL,BUFFERSIZE,BUFFERSIZE,NULL);
        emptySemaphore = CreateSemaphore(NULL,0,BUFFERSIZE,NULL);
        for(int i = 0;i < 5;i++)
        {
            HANDLE handle1 = CreateThread(NULL,0,Producer,NULL,0,NULL);
            CloseHandle(handle1);
        }
        for(int i = 0;i < 5;i++)
        {
            HANDLE handle2 = CreateThread(NULL,0,Consumer,NULL,0,NULL);
            CloseHandle(handle2);
        }
    
        while(real_product_num < PRODUCT_NUM);
        return 0;
    }
    #include<windows.h>
    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    using namespace std;
    
    const unsigned short Size = 10; // 缓冲区长度
    unsigned short curValue = 0; // 当前产品数
    
    bool g_continue = true;  // 控制程序结束:true(运行);false(结束)
    
    HANDLE g_hMutex; //用于线程间的互斥
    HANDLE g_hFullSemaphore; //当缓冲区满时迫使生产者等待
    HANDLE g_hEmptySemaphore; //当缓冲区空时迫使消费者等待
    DWORD WINAPI Producer(LPVOID); //生产者线程
    DWORD WINAPI Consumer(LPVOID); //消费者线程
    
    int main() {
        //创建各个互斥信号
        g_hMutex = CreateMutex(NULL,FALSE,NULL);
        g_hFullSemaphore = CreateSemaphore(NULL,Size-1,Size-1,NULL);
        g_hEmptySemaphore = CreateSemaphore(NULL,0,Size-1,NULL);
    
        //创建生产者线程
        srand( (unsigned)time( NULL ) );
        int t1 = rand()%(Size+1);
        for (int i = 0; i < t1; i++) {
            HANDLE producer = CreateThread(NULL,0,Producer,NULL,0,NULL);
        }
        //创建消费者线程
        srand( (unsigned)time( NULL ) );
        int t2 = rand()%(Size+1);
        for (int i = 0; i < t2; i++) {
            HANDLE consumer = CreateThread(NULL,0,Consumer,NULL,0,NULL);
        }
    
        while(g_continue){
            if(getchar()) g_continue = false;   //按回车后终止程序运行
        }
        return 0;
    }
    
    void Produce() {
        if (curValue == 10) return;
        cout << "生产之前产品数为:" << curValue << endl;
        curValue++;
        cout << "Produce Succeed" << endl;
        cout << "当前产品数为:" << curValue << endl;
        cout << endl;
    }
    
    void Consume() {
        if (curValue == 0) return;
        cout << "消费之前产品数为:" << curValue << endl;
        curValue--;
        cout << "Consume Succeed" << endl;
        cout << "当前产品数为:" << curValue << endl;
        cout << endl;
    }
    
    //生产者
    DWORD WINAPI Producer(LPVOID lpPara) {
        while(g_continue){
            WaitForSingleObject(g_hFullSemaphore,INFINITE);
            WaitForSingleObject(g_hMutex,INFINITE);
            Produce();
            Sleep(1000);
            ReleaseMutex(g_hMutex);
            ReleaseSemaphore(g_hEmptySemaphore,1,NULL);
        }
        return 0;
    }
    
    //消费者
    DWORD WINAPI Consumer(LPVOID lpPara) {
        while(g_continue){
            WaitForSingleObject(g_hEmptySemaphore,INFINITE);
            WaitForSingleObject(g_hMutex,INFINITE);
            Consume();
            Sleep(1000);
            ReleaseMutex(g_hMutex);
            ReleaseSemaphore(g_hFullSemaphore,1,NULL);
        }
        return 0;
    }
    #include <unistd.h>
    
    #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.
    
    struct ItemRepository {
        int item_buffer[kItemRepositorySize]; // 产品缓冲区, 配合 read_position 和 write_position 模型环形队列.
        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) { // item buffer is full, just wait here.
            std::cout << "Producer is waiting for an empty slot...
    ";
            (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(); // 通知消费者产品库不为空.
        lock.unlock(); // 解锁.
    }
    
    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::cout << "Consumer is waiting for items...
    ";
            (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(); // 通知消费者产品库不为满.
        lock.unlock(); // 解锁.
    
        return data; // 返回产品.
    }
    
    
    void ProducerTask() // 生产者任务
    {
        for (int i = 1; i <= kItemsToProduce; ++i) {
            // sleep(1);
            std::cout << "Produce the " << i << "^th item..." << std::endl;
            ProduceItem(&gItemRepository, i); // 循环生产 kItemsToProduce 个产品.
        }
    }
    
    void ConsumerTask() // 消费者任务
    {
        static int cnt = 0;
        while(1) {
            sleep(1);
            int item = ConsumeItem(&gItemRepository); // 消费一个产品.
            std::cout << "Consume the " << item << "^th item" << std::endl;
            if (++cnt == kItemsToProduce) break; // 如果产品消费个数为 kItemsToProduce, 则退出.
        }
    }
    
    void InitItemRepository(ItemRepository *ir)
    {
        ir->write_position = 0; // 初始化产品写入位置.
        ir->read_position = 0; // 初始化产品读取位置.
    }
    
    int main()
    {
        InitItemRepository(&gItemRepository);
        std::thread producer(ProducerTask); // 创建生产者线程.
        std::thread consumer(ConsumerTask); // 创建消费之线程.
        producer.join();
        consumer.join();
    }
  • 相关阅读:
    Collections接口下的Comparetor类和Comparable接口排序
    MySQL(二)、数据库数据类型
    MySQL(表设置、详细说明查询操作)、JDBC基础
    IO流:对象流、Poperties类
    IO流:System.in、SequenceInputStream合并流、内存输入输出流、数据流
    IO流:文件对象、字符流、字节流、缓冲流
    泛型
    集合
    String常用方法、toString()、equals()、compareTo()
    继承、抽象、接口、封装
  • 原文地址:https://www.cnblogs.com/dynas/p/7018554.html
Copyright © 2020-2023  润新知