#include <iostream> #include <windows.h> #include <time.h> using namespace std; static const int BUFFERSIZE = 10; static const int PRODUCT_NUM = 50; HANDLE mutex; HANDLE fullSemaphore; HANDLE emptySemaphore; int real_product_num = 0; int curVal = 0; void produce() { if(curVal >= BUFFERSIZE)return; cout<<"当前产品数为:"<<curVal<<" "; curVal++; cout<<"生产后产品数为:"<<curVal<<endl; real_product_num++; } DWORD WINAPI Producer(LPVOID lpPara) { while(real_product_num < PRODUCT_NUM) { WaitForSingleObject(fullSemaphore,INFINITE); WaitForSingleObject(mutex,INFINITE); produce(); Sleep(80); ReleaseMutex(mutex); ReleaseSemaphore(emptySemaphore,1,NULL); } } void consume() { if(curVal <= 0)return; cout<<"当前产品数为:"<<curVal<<" "; curVal--; cout<<"消费后产品数为:"<<curVal<<endl; } DWORD WINAPI Consumer(LPVOID lpPara) { while(real_product_num < PRODUCT_NUM) { WaitForSingleObject(emptySemaphore,INFINITE); WaitForSingleObject(mutex,INFINITE); consume(); Sleep(100); ReleaseMutex(mutex); ReleaseSemaphore(fullSemaphore,1,NULL); } } int main() { mutex = CreateMutex(NULL,FALSE,NULL); fullSemaphore = CreateSemaphore(NULL,BUFFERSIZE,BUFFERSIZE,NULL); emptySemaphore = CreateSemaphore(NULL,0,BUFFERSIZE,NULL); for(int i = 0;i < 5;i++) { HANDLE handle1 = CreateThread(NULL,0,Producer,NULL,0,NULL); CloseHandle(handle1); } for(int i = 0;i < 5;i++) { HANDLE handle2 = CreateThread(NULL,0,Consumer,NULL,0,NULL); CloseHandle(handle2); } while(real_product_num < PRODUCT_NUM); return 0; }
#include<windows.h> #include<iostream> #include<stdio.h> #include<stdlib.h> #include<time.h> using namespace std; const unsigned short Size = 10; // 缓冲区长度 unsigned short curValue = 0; // 当前产品数 bool g_continue = true; // 控制程序结束:true(运行);false(结束) HANDLE g_hMutex; //用于线程间的互斥 HANDLE g_hFullSemaphore; //当缓冲区满时迫使生产者等待 HANDLE g_hEmptySemaphore; //当缓冲区空时迫使消费者等待 DWORD WINAPI Producer(LPVOID); //生产者线程 DWORD WINAPI Consumer(LPVOID); //消费者线程 int main() { //创建各个互斥信号 g_hMutex = CreateMutex(NULL,FALSE,NULL); g_hFullSemaphore = CreateSemaphore(NULL,Size-1,Size-1,NULL); g_hEmptySemaphore = CreateSemaphore(NULL,0,Size-1,NULL); //创建生产者线程 srand( (unsigned)time( NULL ) ); int t1 = rand()%(Size+1); for (int i = 0; i < t1; i++) { HANDLE producer = CreateThread(NULL,0,Producer,NULL,0,NULL); } //创建消费者线程 srand( (unsigned)time( NULL ) ); int t2 = rand()%(Size+1); for (int i = 0; i < t2; i++) { HANDLE consumer = CreateThread(NULL,0,Consumer,NULL,0,NULL); } while(g_continue){ if(getchar()) g_continue = false; //按回车后终止程序运行 } return 0; } void Produce() { if (curValue == 10) return; cout << "生产之前产品数为:" << curValue << endl; curValue++; cout << "Produce Succeed" << endl; cout << "当前产品数为:" << curValue << endl; cout << endl; } void Consume() { if (curValue == 0) return; cout << "消费之前产品数为:" << curValue << endl; curValue--; cout << "Consume Succeed" << endl; cout << "当前产品数为:" << curValue << endl; cout << endl; } //生产者 DWORD WINAPI Producer(LPVOID lpPara) { while(g_continue){ WaitForSingleObject(g_hFullSemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Produce(); Sleep(1000); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hEmptySemaphore,1,NULL); } return 0; } //消费者 DWORD WINAPI Consumer(LPVOID lpPara) { while(g_continue){ WaitForSingleObject(g_hEmptySemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE); Consume(); Sleep(1000); ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hFullSemaphore,1,NULL); } return 0; }
#include <unistd.h> #include <cstdlib> #include <condition_variable> #include <iostream> #include <mutex> #include <thread> static const int kItemRepositorySize = 10; // Item buffer size. static const int kItemsToProduce = 1000; // How many items we plan to produce. struct ItemRepository { int item_buffer[kItemRepositorySize]; // 产品缓冲区, 配合 read_position 和 write_position 模型环形队列. size_t read_position; // 消费者读取产品位置. size_t write_position; // 生产者写入产品位置. std::mutex mtx; // 互斥量,保护产品缓冲区 std::condition_variable repo_not_full; // 条件变量, 指示产品缓冲区不为满. std::condition_variable repo_not_empty; // 条件变量, 指示产品缓冲区不为空. } gItemRepository; // 产品库全局变量, 生产者和消费者操作该变量. typedef struct ItemRepository ItemRepository; void ProduceItem(ItemRepository *ir, int item) { std::unique_lock<std::mutex> lock(ir->mtx); while(((ir->write_position + 1) % kItemRepositorySize) == ir->read_position) { // item buffer is full, just wait here. std::cout << "Producer is waiting for an empty slot... "; (ir->repo_not_full).wait(lock); // 生产者等待"产品库缓冲区不为满"这一条件发生. } (ir->item_buffer)[ir->write_position] = item; // 写入产品. (ir->write_position)++; // 写入位置后移. if (ir->write_position == kItemRepositorySize) // 写入位置若是在队列最后则重新设置为初始位置. ir->write_position = 0; (ir->repo_not_empty).notify_all(); // 通知消费者产品库不为空. lock.unlock(); // 解锁. } int ConsumeItem(ItemRepository *ir) { int data; std::unique_lock<std::mutex> lock(ir->mtx); // item buffer is empty, just wait here. while(ir->write_position == ir->read_position) { std::cout << "Consumer is waiting for items... "; (ir->repo_not_empty).wait(lock); // 消费者等待"产品库缓冲区不为空"这一条件发生. } data = (ir->item_buffer)[ir->read_position]; // 读取某一产品 (ir->read_position)++; // 读取位置后移 if (ir->read_position >= kItemRepositorySize) // 读取位置若移到最后,则重新置位. ir->read_position = 0; (ir->repo_not_full).notify_all(); // 通知消费者产品库不为满. lock.unlock(); // 解锁. return data; // 返回产品. } void ProducerTask() // 生产者任务 { for (int i = 1; i <= kItemsToProduce; ++i) { // sleep(1); std::cout << "Produce the " << i << "^th item..." << std::endl; ProduceItem(&gItemRepository, i); // 循环生产 kItemsToProduce 个产品. } } void ConsumerTask() // 消费者任务 { static int cnt = 0; while(1) { sleep(1); int item = ConsumeItem(&gItemRepository); // 消费一个产品. std::cout << "Consume the " << item << "^th item" << std::endl; if (++cnt == kItemsToProduce) break; // 如果产品消费个数为 kItemsToProduce, 则退出. } } void InitItemRepository(ItemRepository *ir) { ir->write_position = 0; // 初始化产品写入位置. ir->read_position = 0; // 初始化产品读取位置. } int main() { InitItemRepository(&gItemRepository); std::thread producer(ProducerTask); // 创建生产者线程. std::thread consumer(ConsumerTask); // 创建消费之线程. producer.join(); consumer.join(); }