/*
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);
}