信号量 锁机制 处理生产者-消费者问题

#include<iostream>
#include<cstdlib>
#include<Windows.h>//包含对window系统资源的一些操作函数 包括窗口 光标 线程
using namespace std;

const unsigned short SIZE_OF_BUFF = 10;//缓冲区的容量
int g_buffer[SIZE_OF_BUFF];//缓冲区是一个循环队列
HANDLE g_hMutex;//用于进程间的互锁
HANDLE g_hFullItem;//缓冲区被占用的项
HANDLE g_hEmptyItem;//缓冲区中未被占用的项

DWORD WINAPI PRODUCER(LPVOID);
DWORD WINAPI CONSUMER(LPVOID);//指向线程的指针

unsigned short productID = 0;
unsigned short consumerID = 0;
unsigned short in = 0;//产品进入缓冲区的下标
unsigned short out = 0;//产品离开缓冲区的下标


bool g_continue = true;//用于终止程序判断

int main()
{
    g_hMutex = CreateMutex(NULL, false, NULL);
    g_hFullItem = CreateSemaphore(NULL, 0, SIZE_OF_BUFF, NULL);
    g_hEmptyItem = CreateSemaphore(NULL, SIZE_OF_BUFF, SIZE_OF_BUFF, NULL);
    for (int i = 0; i < SIZE_OF_BUFF; i++)//初始化缓冲区
    {
        g_buffer[i] = -1;
    }
    const unsigned short PRODUCER_COUNT = 3;//生产者线程数
    const unsigned short CONSUMER_COUNT = 2;//消费者线程数
    const unsigned short THREAD_COUNT = PRODUCER_COUNT + CONSUMER_COUNT;//总的线程数
    HANDLE hThread[THREAD_COUNT];//线程句柄数组
    DWORD producerID[PRODUCER_COUNT];
    DWORD consumerID[CONSUMER_COUNT];//存储创建的线程ID 必须为DWORD类型
    for (int i = 0; i < PRODUCER_COUNT; i++)//创建生产者线程
    {
        hThread[i] = CreateThread(NULL, 0, PRODUCER, NULL, 0, &producerID[i]);
        if (hThread[i] == NULL) return -1;
    }
    for (int i = 0; i < CONSUMER_COUNT; i++)//创建消费者线程
    {
        hThread[i + PRODUCER_COUNT] = CreateThread(NULL, 0, CONSUMER, NULL, 0, &consumerID[i]);
        if (hThread[i + PRODUCER_COUNT] == NULL) return -1;

    }
    while (g_continue)
    {
        if (getchar())//从键盘输入任何一个字符 终止程序
        {
            g_continue = false;
        }
    }
    return 0;
}
void Produce()
{
    cout << endl << "Producing " << ++productID << " ";
    cout << "succeed" << endl;
}
void Append()
{
    cout << "Appending a product ... " << endl;
    g_buffer[in] = productID;
    in = (in + 1) % SIZE_OF_BUFF;//数组区域循环输入
    cout << "succeed" << endl;
    for (int i = 0; i < SIZE_OF_BUFF; i++)
    {
        cout << i << ": ";
        if (g_buffer[i] == -1)
            cout << "null";
        else
            cout << g_buffer[i];
        cout << endl;
    }
}
void Take()
{
    cout << "Taking a product..." << endl;
    consumerID = g_buffer[out];
    g_buffer[out] = -1;
    out = (out + 1) % SIZE_OF_BUFF;
    cout << "succeed" << endl;
    for (int i = 0; i < SIZE_OF_BUFF; i++)
    {
        cout << i << ": ";
        if (g_buffer[i] == -1)
            cout << "null";
        else
            cout << g_buffer[i];
        cout << endl;
    }
}
void Consume()
{
    cout << "Consuming " << consumerID << " ";
    cout << "succeed" << endl;
}
//生产者线程
DWORD WINAPI PRODUCER(LPVOID lpPara)
{
    while (g_continue)
    {
        int i = rand() % 5;
        Sleep(i * 1000);
        WaitForSingleObject(g_hEmptyItem, INFINITE);//等待信号灯 等待g_hEmptyItem信号被触发 然后返回 在此期间 线程处于挂起状态
        WaitForSingleObject(g_hMutex, INFINITE);//等待缓冲区未被锁
        Produce();//生产一个商品
        Append();//加入缓冲区
        ReleaseMutex(g_hMutex);
        ReleaseSemaphore(g_hFullItem, 1, NULL);//释放信号量 表示缓冲区被占据的空间+1
    }
    return 0;
}
//消费者线程
DWORD WINAPI CONSUMER(LPVOID lpPara)
{
    while (g_continue)
    {
        int i = rand() % 5;
        Sleep(i * 1000);//ms为单位
        WaitForSingleObject(g_hFullItem, INFINITE);
        WaitForSingleObject(g_hMutex, INFINITE);
        Take();//从缓冲区取一个商品
        Consume();//消费
        ReleaseMutex(g_hMutex);
        ReleaseSemaphore(g_hEmptyItem, 1, NULL);
    }
    return 0;
}

都是框架式的东西 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值