生产者消费者模型

#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...\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(); // 通知消费者产品库不为空.
    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...\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(); // 通知消费者产品库不为满.
    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();
}

 

posted @ 2017-06-15 16:30  mximo  阅读(265)  评论(0编辑  收藏  举报