生产者消费者问题:使用信号量和互斥锁的 C++ 实现
这是一个生产者消费者问题的解决方案,使用了信号量和互斥锁来实现线程同步和互斥。代码中定义了一个大小为 10 的缓冲区,生产者线程每次向缓冲区中插入一个随机数,消费者线程每次从缓冲区中取出一个数。当缓冲区满时,生产者线程需要等待,当缓冲区为空时,消费者线程需要等待。具体实现中,使用了 Windows API 中的 CreateMutex、CreateSemaphore、WaitForSingleObject、ReleaseMutex、ReleaseSemaphore 等函数。最后,程序运行时间设为了 400000 毫秒,即约为 6 分钟。
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<windows.h>
using namespace std;
const int BUFFER_SIZE=10;
int buffer[BUFFER_SIZE];
int front,rear;
bool full;
HANDLE Mutex;
HANDLE Full;
HANDLE Empty;
void showBuffer(){
cout'buffer: ';
if(front!=rear||full){
int i=front;
do{
cout<<buffer[i]' ';
i=(i+1)%BUFFER_SIZE;
}while(i!=rear);
}else
cout'empty';
cout'\n*******************************'\n<<endl;
}
int insert_item(int item){
int condition = -1;
WaitForSingleObject(Empty,INFINITE);
WaitForSingleObject(Mutex,INFINITE);
if(!full){
buffer[rear]= item;
rear=(rear+1)%BUFFER_SIZE;
if(rear==front)full=true;
condition=0;
cout'producer produced '<<item<<endl;
showBuffer();
}
ReleaseMutex(Mutex);
ReleaseSemaphore(Full,1,NULL);
return condition;
}
int remove_item(int item){
int condition = -1;
WaitForSingleObject(Full,INFINITE); //获得信号量的一个占有权
WaitForSingleObject(Mutex,INFINITE);//加锁
if(front!=rear||full){
item=buffer[front];
front=(front+1)%BUFFER_SIZE;
full=false;
condition=0;
cout'consumer comsumed '<<item<<endl;
showBuffer();
}
ReleaseMutex(Mutex); //解锁
ReleaseSemaphore(Empty,1,NULL); // 释放信号量的一个占有权
return condition;
}
DWORD WINAPI producer(void *param){
srand((unsigned)time(0));
for(int i=0;;++i){
Sleep((rand()%50)+2000);
insert_item(rand()%BUFFER_SIZE);
}
};
DWORD WINAPI consumer(void *param){
srand((unsigned)time(0));
for(int j=0;;j++){
Sleep((rand()%100)+2500);
remove_item(rand()%BUFFER_SIZE);
}
};
int main(int argc, char *argv[]){
front=0;
rear=0;
full=false;
Mutex=CreateMutex(NULL,FALSE,NULL);
Full=CreateSemaphore(NULL,0,5,NULL); //创建一个信号量
Empty=CreateSemaphore(NULL,5,5,NULL);
CreateThread(NULL,0,producer,NULL,0,NULL);
CreateThread(NULL,0,consumer,NULL,0,NULL);
Sleep(400000);
return 0;
}
代码解释:
- 头文件包含:
iostream:用于标准输入输出cstdlib:用于随机数生成ctime:用于获取当前时间windows.h:用于使用 Windows API
- 全局变量定义:
BUFFER_SIZE:缓冲区大小,定义为 10buffer:用于存储数据的缓冲区front:缓冲区前端指针rear:缓冲区后端指针full:指示缓冲区是否已满Mutex:互斥锁,用于保证同一时刻只有一个线程访问缓冲区Full:信号量,用于控制生产者线程,当缓冲区满时,生产者线程需要等待该信号量Empty:信号量,用于控制消费者线程,当缓冲区为空时,消费者线程需要等待该信号量
- 函数定义:
showBuffer():用于打印缓冲区内容insert_item():生产者线程的插入操作,将随机数插入缓冲区,并处理缓冲区满的情况remove_item():消费者线程的删除操作,从缓冲区中取出一个数,并处理缓冲区空的情况producer():生产者线程,不断生成随机数并插入缓冲区consumer():消费者线程,不断从缓冲区中取出数据
- 主函数:
- 初始化全局变量
- 创建互斥锁、信号量
- 创建生产者线程和消费者线程
- 等待 400000 毫秒(约 6 分钟)
- 返回 0
代码使用 CreateMutex 创建互斥锁,CreateSemaphore 创建信号量。WaitForSingleObject 用于等待互斥锁或信号量,ReleaseMutex 用于释放互斥锁,ReleaseSemaphore 用于释放信号量。
代码的核心思想是使用信号量来控制生产者和消费者线程的执行速度,使用互斥锁来保证同一时刻只有一个线程访问缓冲区,从而避免数据竞争。
希望这段代码解释对您有所帮助!如果您还有其他问题,请随时提问。
原文地址: https://www.cveoy.top/t/topic/ocyN 著作权归作者所有。请勿转载和采集!