C++编程模拟生产者消费者模型

生产者消费者问题是操作系统中典型的进程同步互斥问题,(英语:Producer-Consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。

该问题描述了两个共享固定大小缓冲区的线程“生产者”(Producer)和“消费者”(Consumer)在实际运行时会发生的问题。

生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。

问题的约束条件是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中为空时消耗数据。

下面的C++程序代码用水果的例子模拟生产者消费者模型,生产者随机生产水果列表{"Apple","Banana","Cherry","Orange","Pear","Peach","WaterMelon"}中的一种,缓冲区用数组模拟。

程序应用了互斥锁和信号量,使用了CreateMutex,ReleaseMutex,CreateSemaphore,ReleaseSemaphore,WaitForSingleObject等Windows下的线程函数。

C++代码如下:

#include <iostream>
#include <cstdlib>
#include <windows.h>
#include <string>
#include <time.h>

using namespace std;

const int limit = 30;  //生产总量
const int maxsize = 10; //缓冲区大小
const int kind = 7;  //水果的种类
int bufIdx = 0;    //当前缓冲区下标

string buf[maxsize];    //缓冲区 (字符串)

//伪造的产品
string product[] = {"Apple","Banana","Cherry","Orange","Pear","Peach","WaterMelon"};

HANDLE mutex,full,empty; //互斥锁,占用信号量,空闲信号量

HANDLE disp;    //用于控制屏幕打印的互斥锁

//生产者子过程
DWORD WINAPI Producer(LPVOID param)
{
    int ct,idx;
    const int pwait = 100;
    srand(time(NULL)); //随机数播种

    WaitForSingleObject(disp, INFINITE);
    cout << "Producer Start!" << endl << endl;
    ReleaseMutex(disp);

    for (ct = 0; ct < limit; ct ++)
    {
        idx = rand() % kind;

        WaitForSingleObject(disp, INFINITE);
        cout << product[idx] << " is ready!" << endl << endl;
        ReleaseMutex(disp);

        WaitForSingleObject(empty, INFINITE); //请求一个空缓冲区,阻塞
        WaitForSingleObject(mutex, INFINITE); //请求互斥锁,阻塞
        buf[bufIdx ++] = product[idx];

        WaitForSingleObject(disp, INFINITE);
        cout << product[idx] << " added to slot No. " << bufIdx << endl << endl;
        ReleaseMutex(disp);

        ReleaseMutex(mutex);    //释放互斥锁
        ReleaseSemaphore (full, 1, NULL);   //signal(full)
        Sleep(rand() % pwait + 100);  //休息一会
    }

    WaitForSingleObject(disp, INFINITE);
    cout << "Producer Quit!" << endl << endl;
    ReleaseMutex(disp);

    return 0;
}

//消费者子过程
DWORD WINAPI Consumer(LPVOID param)
{
    int ct;
    const int cwait = 300;
    string stuff;
    srand(time(NULL));

    WaitForSingleObject(disp, INFINITE);
    cout << "Consumer Start!" << endl << endl;
    ReleaseMutex(disp);

    for (ct = 0; ct < limit; ct ++)
    {
        WaitForSingleObject(full, INFINITE); //请求一个满缓冲区,阻塞
        WaitForSingleObject(mutex, INFINITE); //请求互斥锁,阻塞
        stuff = buf[-- bufIdx];

        WaitForSingleObject(disp, INFINITE);
        cout << "Consumer get " << stuff << " from slot No. " << (bufIdx + 1) << endl << endl;
        ReleaseMutex(disp);

        ReleaseMutex(mutex);    //释放互斥锁
        ReleaseSemaphore (empty, 1, NULL);   //signal(empty)
        Sleep(rand() % cwait + 100);  //休息一会
    }

    WaitForSingleObject(disp, INFINITE);
    cout << "Consumer Quit!" << endl << endl;
    ReleaseMutex(disp);

    return 0;
}

int main()
{
    //生产者线程与消费者线程的线程ID
    DWORD ProducerID, ConsumerID;
    //线程句柄
    HANDLE ProducerHandle, ConsumerHandle;

    //创建屏幕打印互斥锁
    disp = CreateMutex(NULL, FALSE, NULL);

    //创建生产者线程
    ProducerHandle = CreateThread(NULL, 0, Producer, NULL, 0, &ProducerID);
    //创建消费者线程
    ConsumerHandle = CreateThread(NULL, 0, Consumer, NULL, 0, &ConsumerID);

    //创建互斥锁
    mutex = CreateMutex(NULL, FALSE, NULL);
    //创建缓冲区占用信号量
    full = CreateSemaphore (NULL, 0, maxsize, "full");
    //创建缓冲区空闲信号量
    empty = CreateSemaphore (NULL, maxsize, maxsize, "empty");

    //等待直到生产者线程执行完成
    if (ProducerHandle != NULL)
    {
        WaitForSingleObject(ProducerHandle, INFINITE);
        CloseHandle(ProducerHandle);
    }
    //等待直到消费者线程执行完成
    if (ConsumerHandle != NULL)
    {
        WaitForSingleObject(ConsumerHandle, INFINITE);
        CloseHandle(ConsumerHandle);
    }
    system("pause");
}

运行结果如下:

Producer Start!
Consumer Start!
Cherry is ready!
Cherry added to slot No. 1
Consumer get Cherry from slot No. 1
Orange is ready!
Orange added to slot No. 1
Apple is ready!
Apple added to slot No. 2
Consumer get Apple from slot No. 2
Cherry is ready!
Cherry added to slot No. 2
WaterMelon is ready!
WaterMelon added to slot No. 3
Consumer get WaterMelon from slot No. 3
Peach is ready!
Peach added to slot No. 3
Consumer get Peach from slot No. 3
Banana is ready!
Banana added to slot No. 3
Orange is ready!
Orange added to slot No. 4
Consumer get Orange from slot No. 4
Pear is ready!
Pear added to slot No. 4
Peach is ready!
Peach added to slot No. 5
Consumer get Peach from slot No. 5
Consumer get Pear from slot No. 4
Cherry is ready!
Cherry added to slot No. 4
WaterMelon is ready!
WaterMelon added to slot No. 5
Consumer get WaterMelon from slot No. 5
Peach is ready!
Peach added to slot No. 5
WaterMelon is ready!
WaterMelon added to slot No. 6
Consumer get WaterMelon from slot No. 6
WaterMelon is ready!
WaterMelon added to slot No. 6
Cherry is ready!
Cherry added to slot No. 7
Consumer get Cherry from slot No. 7
Banana is ready!
Banana added to slot No. 7
Orange is ready!
Orange added to slot No. 8
Consumer get Orange from slot No. 8
Peach is ready!
Peach added to slot No. 8
Consumer get Peach from slot No. 8
Orange is ready!
Orange added to slot No. 8
Peach is ready!
Peach added to slot No. 9
Consumer get Peach from slot No. 9
Orange is ready!
Orange added to slot No. 9
WaterMelon is ready!
WaterMelon added to slot No. 10
Consumer get WaterMelon from slot No. 10
Orange is ready!
Orange added to slot No. 10
Apple is ready!
Consumer get Orange from slot No. 10
Apple added to slot No. 10
Cherry is ready!
Consumer get Apple from slot No. 10
Cherry added to slot No. 10
Consumer get Cherry from slot No. 10
Pear is ready!
Pear added to slot No. 10
Consumer get Pear from slot No. 10
Orange is ready!
Orange added to slot No. 10
Pear is ready!
Consumer get Orange from slot No. 10
Pear added to slot No. 10
Banana is ready!
Consumer get Pear from slot No. 10
Banana added to slot No. 10
Consumer get Banana from slot No. 10
Producer Quit!
Consumer get Orange from slot No. 9
Consumer get Orange from slot No. 8
Consumer get Banana from slot No. 7
Consumer get WaterMelon from slot No. 6
Consumer get Peach from slot No. 5
Consumer get Cherry from slot No. 4
Consumer get Banana from slot No. 3
Consumer get Cherry from slot No. 2
Consumer get Orange from slot No. 1
Consumer Quit!
请按任意键继续. . .

本文链接:http://bookshadow.com/weblog/2014/05/16/producer-consumer-demo-program-in-cpp/
请尊重作者的劳动成果,转载请注明出处!书影博客保留对文章的所有权利。

如果您喜欢这篇博文,欢迎您捐赠书影博客: ,查看支付宝二维码

Pingbacks已关闭。

评论
  1. 你会在我身边 你会在我身边 发布于 2014年9月28日 08:56 #

    代码牛人!!

张贴您的评论