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;
}
如果有问题欢迎评论指正
浙公网安备 33010602011771号