http://www.cnblogs.com/steady/archive/2011/04/02/2003168.html
/* 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);
}