生产者消费者

来源:互联网 发布:net软件开发培训 编辑:程序博客网 时间:2024/05/22 04:42
操作系统的经典问题
生产者和消费者问题的编程,使用语言为C++,这是操作系统实验课上的编程,拿出来和大家分享,不足之处还望指出,谢谢。
// 生产者消费者#include<iostream>#include<queue>#include<Windows.h>using namespace std;struct Product//生产的产品{int id;//产品的idint bufferPos;//产品所在的缓冲池的位置};queue<Product> g_queue;//缓冲池队列HANDLE bufferFullSemaphore;//缓冲池满的信号量HANDLE bufferEmptySemaphore;//缓冲池空的信号量HANDLE mutex;//操作互斥锁static int num = 0;//当前池子的位置DWORD WINAPI producerFunc(LPVOID n);//生产者进程函数DWORD WINAPI consumerFunc(LPVOID n);//消费者进程函数int bufferSize;//缓冲池大小int CostTask = 0;//消费多少个就结束int CostNum = 0;//当前消费的数量DWORD thrdId;class Producer {//生产者的类public:Producer() {handle = CreateThread(NULL, 0, producerFunc, this, 0, &thrdId);//创建一个线程ID = GetThreadId(this->handle);//将线程的ID设置为此生产者的IDproductNum = 0;//已经生产的产品的数量product.id = ID;//将此生产者生产的产品ID设置为生产者ID}int getID() {return ID;}int getProductNum() {return productNum;}void IncProductNum() {productNum++;}HANDLE getHandle() {return handle;}Product getProduct() {return product;}void setProductPos(int n) {product.bufferPos = n;}protected:HANDLE handle;int productNum;int ID;Product product;};class Consumer {//消费者类,基本同上public:Consumer() {handle = CreateThread(NULL, 0, consumerFunc, this, 0, &thrdId);//其中this传递对象的指针ID = GetThreadId(this->handle);consumeNum = 0;}int getID() {return ID;}int getConsumeNum() {return consumeNum;}void IncConsumeNum() {consumeNum++;}HANDLE getHandle() {return handle;}protected:HANDLE handle;int consumeNum;int ID;};DWORD WINAPI producerFunc(LPVOID n){Producer * thisInfo = reinterpret_cast<Producer*>(n);//将无类型的指针强制转化为我们需要类型的指针while (true){WaitForSingleObject(bufferEmptySemaphore, INFINITE);//等待buffer为空的信号量,意思是当buffer不满的时候,可以进行WaitForSingleObject(mutex, INFINITE);//等待操作的信号量if (CostNum<CostTask)//当当前的消费数量小于我们的目标数量时,进行操作{thisInfo->setProductPos(num);g_queue.push(thisInfo->getProduct());//将产品放入缓冲池SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN);cout << "编号为:" << thisInfo->getID() << "生产了一件产品,放入" << num % bufferSize << "号缓冲池" << endl;thisInfo->IncProductNum();//此生产者生产数量+1num++;//缓冲池移向下一个位置ReleaseMutex(mutex);//释放操作锁ReleaseSemaphore(bufferFullSemaphore, 1, NULL);//指定信号量+1Sleep(500);}else{ReleaseMutex(mutex);//释放操作锁ReleaseSemaphore(bufferFullSemaphore, 1, NULL);//指定信号量+1Sleep(500);break;}}return 0;}DWORD WINAPI consumerFunc(LPVOID n){Consumer* thisInfo = reinterpret_cast<Consumer*>(n);while (true){WaitForSingleObject(bufferFullSemaphore, INFINITE);WaitForSingleObject(mutex, INFINITE);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);if (CostNum < CostTask){thisInfo->IncConsumeNum();cout << "编号为:" << thisInfo->getID() << "消费了编号为:" << g_queue.front().id << "生产的一件产品,在" << g_queue.front().bufferPos % bufferSize << "号缓冲池" << endl;CostNum++;g_queue.pop();ReleaseMutex(mutex);ReleaseSemaphore(bufferEmptySemaphore, 1, NULL);//指定信号量+1Sleep(500);}else{ReleaseMutex(mutex);//释放操作锁ReleaseSemaphore(bufferFullSemaphore, 1, NULL);//指定信号量+1Sleep(500);break;}}return 0;}int main(){int P, C;HANDLE handle[2];Producer* producers;Consumer* consumers;HANDLE* handles;mutex = CreateMutex(NULL, false, NULL);//false代表开始的时候不属于任何进程cout << "消费者生产者问题----Way" << endl;cout << "-----------------------------------"<< endl;cout << "请输入生产者数量:";cin >> P;cout << "请输入消费者数量:";cin >> C;cout << "请输入缓冲池大小:";cin >> bufferSize;cout << "请输入最大消费数量:";cin >> CostTask;bufferFullSemaphore = CreateSemaphore(NULL, 0, bufferSize, NULL);//初始资源设定为bufferEmptySemaphore = CreateSemaphore(NULL, bufferSize, bufferSize, NULL); //初始资源为producers = new Producer[P];consumers = new Consumer[C];WaitForSingleObject(producers[0].getHandle(), INFINITE);//等待第一个生产者返回,加这个语句的目的是,为了等所有的生产者和消费者完成任务以后,再执行往后的语句,不然由于并行的原因,最后打印结果会不正确for ( int i = 0; i < P; i++){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);cout << "编号为:" << producers[i].getID() << "生产了:" << producers[i].getProductNum() << "件商品"<<endl;}for (int i = 0; i < C ; i++){cout << "编号为:" << consumers[i].getID() << "消费了:" << consumers[i].getConsumeNum() << "件商品"<<endl;}for (int i = 0; i < P; i++){CloseHandle(producers[i].getHandle());}for (int i = 0; i < C; i++){CloseHandle(consumers[i].getHandle());}delete producers, consumers;CloseHandle(bufferEmptySemaphore);CloseHandle(bufferFullSemaphore);CloseHandle(mutex);getchar();getchar();return 0;}


原创粉丝点击