并发控制-生产者-消费者问题

本文介绍了一个基于Windows环境的生产者与消费者问题的实现案例。通过创建多个生产者与消费者线程,利用信号量和互斥锁实现了线程间的同步与资源保护。详细展示了线程创建、信号量操作及线程间通信的具体过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
生产者与消费者问题的实现。
创建一组“生产者”线程和一组“消费者”线程,并建立一个长度为N的缓冲池。
“生产者”向缓冲区输入数据,“消费者”从缓冲区读出数据。
当缓冲区满时,“生产者”必须阻塞,等待“消费者”取走缓冲区数据后将其唤醒。
当缓冲区空时,“消费者”阻塞,等待“生产者”生产了产品后将其唤醒。
用信号量实现“生产者”与“消费者”线程之间的同步。

*/
#include <windows.h>
#include <iostream>
#include<cstdio>


const int PCOUNT = 5; //生产者的个数
const int CCOUNT = 5; //消费者的个数
const int N = 8; //缓冲池中缓冲区数量
int ProductID = 0; //生产产品号
int ConsumeID = 0; //消费产品号
int in = 0;
int out = 0;
int total = 0; //库存量
int Buffer[N]; //缓冲池
int buffer[N];
bool stop = false;
HANDLE Mutex; //互斥信号量实现缓冲池的互斥使用
HANDLE Full; //缓冲池中满缓冲区的数量
HANDLE Empty; //缓冲池中空缓冲区的数量

SYSTEMTIME systime;

DWORD WINAPI Producer(LPVOID); //生产者线程
DWORD WINAPI Consumer(LPVOID); //消费者线程

int main()
{
//创建各个互斥信号
Mutex = CreateMutex(NULL,FALSE,NULL);
Full = CreateSemaphore(NULL,N-1,N-1,NULL);
Empty = CreateSemaphore(NULL,0,N-1,NULL);
//创建互斥信号量失败
if (Mutex == NULL)
{
printf("CreateMutex error: %d\n", GetLastError());
return 0;
}
//创建Full信号量失败
if (Full == NULL)
{
printf("CreateSemaphoreFull error: %d\n", GetLastError());
return 0;
}
//创建Empty信号量失败
if (Empty == NULL)
{
printf("CreateSemaphoreEmpty error: %d\n", GetLastError());
return 0;
}

HANDLE ProducerThreads[PCOUNT]; //生产者线程
HANDLE ConsumerThreads[CCOUNT]; //消费者线程
DWORD producerID[PCOUNT]; //生产者线程的标识符
DWORD consumerID[CCOUNT]; //消费者线程的标识符

//创建生产者线程
for (int i=0;i<PCOUNT;++i)
{
ProducerThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);
if(ProducerThreads[i] == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return 0;
}
}
//创建消费者线程
for (i=0;i<CCOUNT;++i)
{
ConsumerThreads[i]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[i]);
if( ConsumerThreads[i] == NULL)
{
printf("CreateThread error: %d\n", GetLastError());
return 0;
}
}

while(!stop)
{
if(getchar())//按回车后终止程序运行
{
stop = true;
}
}
return 0;
}

//生产
void Produce()
{
printf("生产第%d个产品并加入库存中\n",++ProductID );
Buffer[in] = 1;
in = (in+1)%N;
//输出缓冲区当前的状态
printf("缓冲区当前的状态:");
for (int i=0;i<N;++i)
{
printf("%d",Buffer[i]);
}
printf("\n");
printf("生产者ID:%d\n",GetCurrentThreadId());
buffer[in-1] = GetCurrentThreadId();
printf("产品ID:%d\t\t缓冲区ID:%d\n",ProductID,in);
GetLocalTime(&systime);
printf("时间:%02d:%02d:%02d\t\t", systime.wHour, systime.wMinute, systime.wSecond);
printf("当前库存量:%d\n",++total);
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
}

//消费
void Consume()
{
printf("消费第%d个产品并从库存拿出\n",++ConsumeID);
Buffer[out] = 0;
out = (out+1)%N;
//输出缓冲区当前的状态
printf("缓冲区当前的状态:");
for (int i=0;i<N;++i)
{
printf("%d",Buffer[i]);
}
printf("\n");
printf("消费者ID:%d\n",GetCurrentThreadId());
printf("产品ID:%d\t\t缓冲区ID:%d\t\t来自生产者ID:%d\n",ConsumeID,out,buffer[out-1]);
GetLocalTime(&systime);
printf("时间:%02d:%02d:%02d\t\t", systime.wHour, systime.wMinute, systime.wSecond);
printf("当前库存量:%d\n",--total);
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
}


//生产者
DWORD WINAPI Producer(LPVOID lpPara)
{
while(!stop)
{
WaitForSingleObject(Full,INFINITE);
WaitForSingleObject(Mutex,INFINITE);
Produce();
Sleep(1000);
ReleaseMutex(Mutex);
ReleaseSemaphore(Empty,1,NULL);
}
return 0;
}

//消费者
DWORD WINAPI Consumer(LPVOID lpPara)
{
while(!stop)
{
WaitForSingleObject(Empty,INFINITE);
WaitForSingleObject(Mutex,INFINITE);
Consume();
Sleep(1000);
ReleaseMutex(Mutex);
ReleaseSemaphore(Full,1,NULL);
}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值