生產者消費者問題Semaphore

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);
}
發佈了97 篇原創文章 · 獲贊 1 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章