生产者消费者问题Semaphore

/* productandconsumer. cpp */
#include
<windows.h>
#include
<stdio.h>
#include
<stdlib.h>

typedef HANDLE Semaphore;
//信号量的Windows 原型

#define P(S) WaitForSingleObject (S, INFINITE) //定义P操作
#define V(S) ReleaseSemaphore (S, 1, NULL) //定义V操作

#define CONSUMER_NUM 10 /* 消费者个数*/
#define PRODUCER_NUM 10 /*生产者个数*/
#define BUFFER_NUM 5 /* 缓冲区个数*/

char *fruit[10] = {"桔子", "苹果", "香蕉", "菠萝", "草莓", "荔枝", "樱桃", "葡萄", "桃子", "鸭梨"};

struct Buffer
{
int buf[BUFFER_NUM]; //缓冲区
int out, in; //两个指针
}pub_buf;

Semaphore empty, full, mutex;

//消费者线程
DWORD WINAPI Consumer(LPVOID para)
{
//i 表示第i 个消费者
int i = *(int *)para;
int ptr; //待消费的内容的指针
printf("消费者%03d: 我来啦...\n", i);
Sleep(
300);
while(1)
{
printf(
"消费者%03d: 我要吃...\n", i);
P(full);
//等待产品
P(mutex); //有产品, 先锁住缓冲区pub_buf
ptr = pub_buf.out; //记录消费的物品
pub_buf.out = (pub_buf.out + 1) % BUFFER_NUM; //再移动缓冲区指针
V(mutex); //让其他消费者或生产者使用pub_buf
printf("消费者%03d: 开始吃 buf[%d]=%s\n", i, ptr, fruit[pub_buf.buf[ptr]]);
Sleep (
1000 * rand() % 10 + 110);
printf(
"消费者%03d: 吃完了 buf[%d]=%s\n", i, ptr, fruit[pub_buf.buf[ptr]]);
V(empty);
//消费完毕, 并释放一个缓冲
}
return 0;
}
//生产者线程
DWORD WINAPI Producer (LPVOID para)
{
int i = *(int *)para - CONSUMER_NUM;
int ptr; int data; //产品
printf("生产者%03d:我来啦\n", i);
Sleep(
300);
while (1)
{
printf(
"生产者%03d: 我生产.\n", i);
Sleep(
1000 * rand () %10 + 110);
data
= rand() %10;
printf(
"生产者%03d: 送来一个水果:%s\n", i, fruit[data]);
P(empty);
P(mutex);
//有地方, 先锁住缓冲区pub_buf
ptr = pub_buf.in; //记录消费的物品
pub_buf.in = (pub_buf.in + 1) % BUFFER_NUM;
V(mutex);
//让其他消费者或生产者使用pub_buf
printf("生产者%03d: 开始搁置 buf[%d]=%s\n", i, ptr, fruit[data]);
pub_buf.buf[ptr]
= data;
Sleep(
1000/ 2 * rand () %10 + 110);
printf(
"生产者%03d: 搁置完成 buf[%d]=%s\n", i, ptr, fruit[pub_buf.buf[ptr]]);
V(full);
//放好了完毕, 释放一个产品
}
return 0;
}

int main ( )
{
//线程计数, 前面为消费者线程, 后面为生产者线程
HANDLE hThreadGroup[CONSUMER_NUM + PRODUCER_NUM];
DWORD tid; size_t i
= 0;
//初始化信号量
mutex = CreateSemaphore(NULL, 1, BUFFER_NUM, (LPCWSTR)("mutex"));
empty
= CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, (LPCWSTR)("empty"));
full
= CreateSemaphore(NULL, 0, BUFFER_NUM, (LPCWSTR)("full"));
if (!empty || !full || !mutex)
{
printf(
"Create Semaphone Error!\n");
return - 1;
}
size_t uTotalThreads
= CONSUMER_NUM + PRODUCER_NUM;
for (i = 0; i < CONSUMER_NUM; i++)
{
hThreadGroup[i]
= CreateThread(NULL, 0, Consumer, &i, 0, &tid);
if (hThreadGroup[i] )
WaitForSingleObject(hThreadGroup[i],
10);
}
for (; i < uTotalThreads; i++)
{
hThreadGroup[i]
= CreateThread(NULL, 0, Producer, &i, 0, &tid);
if (hThreadGroup[i])
WaitForSingleObject(hThreadGroup[i],
10);
}
//生产者和消费者的执行
WaitForMultipleObjects(uTotalThreads, hThreadGroup, false, INFINITE);
}
posted @ 2011-04-02 11:50  Cranny  阅读(1291)  评论(1编辑  收藏  举报