您的位置:首页 > 编程语言 > C语言/C++

用C语言实现--生产者与消费者的问题(PV操作)

2011-07-09 11:47 696 查看
用C语言实现--生产者与消费者的问题(PV操作)
2011-06-28 16:48
转载自 智达高远lee
最终编辑 智达高远lee

#include   <windows.h>
#include   <stdio.h>
#include   <stdlib.h>

typedef   HANDLE   Semaphore;   //   信号量的Windows原型
#define   P(S)   WaitForSingleObject(S,   INFINITE)   //   定义Windows下的P操作
#define   V(S)   ReleaseSemaphore(S,   1,   NULL)     //   定义Windows下的V操作

#define   rate   1000

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

char   *thing[10]   =   {"猪耳朵",   "牛肝",   "羊蹄",   "驴肉",   "马肉",   "狗肉",   "猴脑",   "老虎屁股",   "大象肚",   "河马大肠"};

struct   Buffer
{
int   product[BUFFER_NUM];   //   缓冲区
int   start,   end;                   //   两个指针
}   g_buf;

Semaphore   g_semBuffer,   g_semProduct,   g_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(g_semProduct);

//   有产品,先锁住缓冲区   g_buf
P(g_mutex);

//   记录消费的物品
ptr   =   g_buf.start;

//   再移动缓冲区指针
g_buf.start   =   (g_buf.start+1)%BUFFER_NUM;

//   让其他消费者或生产者使用   g_buf
V(g_mutex);

printf("     猪头-%03d:   我吃   buf[%d]   =   %s\n",   i,   ptr,   thing[g_buf.product[ptr]]);

Sleep(rate*rand()%10+110);

//   消费完毕,并释放一个缓冲
printf("     猪头-%03d:   太好了!   buf[%d]   =   %s\n",   i,   ptr,   thing[g_buf.product[ptr]]);
V(g_semBuffer);
}
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(rate*rand()%10+110);

data   =   rand()%10;
printf("工作狂-%03d:   发现一个东西   data   =   %s!\n",   i,   thing[data]);
//   等待存放空间
P(g_semBuffer);

//   有地方,先锁住缓冲区   g_buf
P(g_mutex);

//   记录消费的物品
ptr   =   g_buf.end;

//   再移动缓冲区指针
g_buf.end   =   (g_buf.end+1)%BUFFER_NUM;

//   让其他消费者或生产者使用   g_buf
V(g_mutex);

printf("工作狂-%03d:   搁到   buf[%d]   =   %s\n",   i,   ptr,   thing[data]);
g_buf.product[ptr]   =   data;

Sleep(rate/2*rand()%10+110);

//   放好了完毕,释放一个产品
printf("工作狂-%03d:   buf[%d]   =   %s   放好了,大家吃!\n",   i,   ptr,   thing[g_buf.product[ptr]]);
V(g_semProduct);
}
return   0;
}

int   main(int   argc,   char   *argv[])
{
//   线程技术,前面为消费者线程,后面为生产者线程
HANDLE     hThread[CONSUMER_NUM+PRODUCER_NUM];     //   线程计数

//srand(time());
DWORD   tid;
int   i=0;

//   初始化信号量
g_mutex   =   CreateSemaphore(NULL,   BUFFER_NUM,   BUFFER_NUM,   "mutexOfConsumerAndProducer");
g_semBuffer   =   CreateSemaphore(NULL,   BUFFER_NUM,   BUFFER_NUM,   "BufferSemaphone");
g_semProduct   =   CreateSemaphore(NULL,   0,   BUFFER_NUM,   "ProductSemaphone");

if   (   !g_semBuffer   ||   !g_semProduct   ||   !g_mutex)
{
printf("Create   Semaphone   Error!\n");
return   -1;
}

int   totalThreads   =   CONSUMER_NUM+PRODUCER_NUM;
//   开启消费者线程
printf("先请猪头们上席!\n");
for   (i=0;   i<CONSUMER_NUM;   i++)
{
hThread[i]   =   CreateThread(NULL,   0,   Consumer,   &i,   0,   &tid);
if   (   hThread[i]   )   WaitForSingleObject(hThread[i],   10);
}

printf("厨子们就位!\n");
for   (;   i<totalThreads;   i++)
{
hThread[i]   =   CreateThread(NULL,   0,   Producer,   &i,   0,   &tid);
if   (   hThread[i]   )   WaitForSingleObject(hThread[i],   10);
}

//   生产者和消费者的执行
WaitForMultipleObjects(totalThreads,   hThread,   TRUE,   INFINITE);
return   0;
}

原文链接:http://hi.baidu.com/125580956/blog/item/6708fbc9def91a51f31fe72c.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: