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