Windows下Semaphore 经典生产者消费者
// product_consumer.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include <windows.h> #include <tchar.h> #include <stdio.h> #include <stdlib.h> #define P(S) WaitForSingleObject (S, INFINITE) //定义P操作 #define V(S) ReleaseSemaphore (S, 1, NULL) //定义V操作 #define MUTEX_LOCK(m) WaitForSingleObject(m, INFINITE) #define MUTEX_UNLOCK(m) ReleaseMutex(m) #define CONSUMER_NUM 10 /* 消费者个数 */ #define PRODUCER_NUM 10 /* 生产者个数 */ #define BUFFER_NUM 5 /* 缓冲区个数 */ const char *c_string_fruit[10] = { "桔子", "苹果", "香蕉", "菠萝", "草莓", "荔枝", "樱桃", "葡萄", "桃子", "鸭梨" }; const char *g_item_buffer[BUFFER_NUM] = { 0 }; int g_item_product_index = 0; int g_item_consume_index = 0; HANDLE g_sem_product = NULL; HANDLE g_sem_consume = NULL; HANDLE g_sec_mutex = NULL; //生产者线程 DWORD WINAPI thread_product(LPVOID para) { int i = (int)para; printf("生产者[%02d]: 我来啦 ...\n", i); srand(GetTickCount() + GetCurrentThreadId()); while (true) { printf("生产者[%02d]: 生产中 ...\n", i); Sleep(1000 * rand() % 10 + 110); const char *fruit = c_string_fruit[rand() % _countof(c_string_fruit)]; printf("生产者[%02d]: 生产一个水果: %s\n", i, fruit); P(g_sem_product); MUTEX_LOCK(g_sec_mutex); g_item_buffer[g_item_product_index] = fruit; g_item_product_index = (g_item_product_index + 1) % BUFFER_NUM; MUTEX_UNLOCK(g_sec_mutex); Sleep(1000 / 2 * rand() % 10 + 110); printf("生产者[%02d]: 放置一个水果: %s\n", i, fruit); V(g_sem_consume); } return 0; } //消费者线程 DWORD WINAPI thread_consume(LPVOID para) { int i = (int)para; printf("消费者[%02d]: 我来啦 ...\n", i); srand(GetTickCount() + GetCurrentThreadId()); while (1) { printf("消费者[%02d]: 我要吃 ...\n", i); const char *fruit = NULL; P(g_sem_consume); MUTEX_LOCK(g_sec_mutex); fruit = g_item_buffer[g_item_consume_index]; g_item_buffer[g_item_consume_index] = NULL; g_item_consume_index = (g_item_consume_index + 1) % BUFFER_NUM; MUTEX_UNLOCK(g_sec_mutex); printf("消费者[%02d]: 开始吃 %s\n", i, fruit); Sleep(1000 * rand() % 10 + 110); printf("消费者[%02d]: 吃完毕 %s\n", i, fruit); V(g_sem_product); } return 0; } int main() { setlocale(LC_ALL, "chs"); //初始化信号量 g_sec_mutex = CreateMutex(NULL, FALSE, NULL); g_sem_product = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, _T("SEM_PRODUCT")); g_sem_consume = CreateSemaphore(NULL, 0, BUFFER_NUM, _T("SEM_CONSUME")); if (g_sem_product == NULL || g_sem_consume == NULL || g_sec_mutex == NULL) { printf("创建信号量或互斥体失败!\n"); return -1; } //线程计数, 前面为消费者线程, 后面为生产者线程 HANDLE hThreadConsume[CONSUMER_NUM] = { 0 }; HANDLE hThreadProduct[PRODUCER_NUM] = { 0 }; for (int i = 0; i < CONSUMER_NUM; i++) { DWORD dwThreadId = 0; hThreadConsume[i] = CreateThread(NULL, 0, thread_consume, (LPVOID)i, 0, &dwThreadId); if (hThreadConsume[i] == NULL) { printf("创建消费者线程失败!\n"); return -1; } } for (int i = 0; i < PRODUCER_NUM; i++) { DWORD dwThreadId = 0; hThreadProduct[i] = CreateThread(NULL, 0, thread_product, (LPVOID)i, 0, &dwThreadId); if (hThreadConsume[i] == NULL) { printf("创建生产者者线程失败!\n"); return -1; } } //生产者和消费者的执行 WaitForMultipleObjects(CONSUMER_NUM, hThreadConsume, TRUE, INFINITE); WaitForMultipleObjects(PRODUCER_NUM, hThreadProduct, TRUE, INFINITE); return 0; }
如果有问题欢迎评论指正