vc实现生产者消费者

生产者消费者问题是一个著名的进程同步问题。它的描述是:有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区中;消费者进程可从缓冲区中取走产品去消费。尽管所有的生产者进程和消费者进程都是以异步方式运行,但它们之间必须保持同步,即不允许消费者进程到一个空的缓冲区取产品,也不允许生产者进程向一个已装满产品且尚未取走的缓冲区投放产品。

    我们利用一个数组来表示上述具有n个缓冲区的循环缓冲池。用in来指示下一个可投放产品的缓冲区,每当生产者进程生产并投放一个产品后,in下移;用out来指示下一个可从中获取产品的缓冲区,每当消费者进程取走一个产品后,out下移。利用信号量原语Wait()和Release()实现进程的同步与互斥。程序中,缓冲池有128个缓冲区,当生产者进程生产了32个产品后,程序停止,按#键退出程序,其他任意键继续。程序如下:

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>

DWORD WINAPI Producer(LPVOID lpParam);
DWORD WINAPI Consumer(LPVOID lpParam);
DWORD WINAPI KeyThread(LPVOID lpParam);

HANDLE Full,Empty;
HANDLE hMutex;
int buffer[128], bufn=32;
bool producerflg=true,consumerflg=true;
DWORD dwThreadId,dwThreadId1,dwThreadId2;
DWORD dwThrdParam,dwThrdParam1,dwThrdParam2;
HANDLE hThread,hThread1,hThread2;
ULONG ExCode=0;

void main(int argc, char* argv[])
{
  memset(buffer,-1,sizeof(int)*bufn); //初始化buffer的值为-1
  hMutex=CreateMutex(NULL,FALSE,"NameOfMutexObject"); //创建互斥锁hMutex
  Full=CreateSemaphore(NULL,0,bufn,NULL); //创建信号量Full
  Empty=CreateSemaphore(NULL,bufn,bufn,NULL); //创建信号量Empty
  hThread1=CreateThread(NULL,0,Producer,&dwThrdParam1,0,&dwThreadId1); //创建线程Producer
  hThread2=CreateThread(NULL,0,Consumer,&dwThrdParam2,0,&dwThreadId2); //创建线程Consumer
  do{
    GetExitCodeThread(hThread1,&ExCode); //主线程循环取Producer线程的退出码ExCode
  }while (ExCode==STILL_ACTIVE); //如果还处于运行状态则继续
}

DWORD WINAPI Producer(LPVOID lpParam)
{
  int in=0;
  char c;
  do{
    WaitForSingleObject(Empty, INFINITE); //信号量Empty做wait操作
    WaitForSingleObject(hMutex, INFINITE); //信号量hMutex做wait操作
    buffer[in]=abs(rand()); //随机数取绝对值后赋予buffer[]
    printf("p[%d]=%d, ",in,buffer[in]); //生产产品
    in=(in+1) % bufn;  //in下移
    if (in==0) {
      c=_getch();
      if (c=='#') return 0;  //按#退出程序,
      printf("/n");
    }
    ReleaseMutex(hMutex); //信号量hMutex做signal操作
    ReleaseSemaphore(Full,1,NULL); //信号量Full做signal操作
  }while(producerflg==true);
  return 0;
}

DWORD WINAPI Consumer(LPVOID lpParam)
{
  int out=0,val;
  do{
    WaitForSingleObject(Full, INFINITE);
    WaitForSingleObject(hMutex, INFINITE);
    val=buffer[out];
    printf("c[%d]=%d, ",out,val); //消费产品
    buffer[out]=-1;
    out=(out+1) % bufn;  //out下移
    ReleaseMutex(hMutex);
    ReleaseSemaphore(Empty,1,NULL);
  }while (consumerflg==true);
  return 0;
}

输出结果为:

p[0]=41, p[1]=18467, p[2]=6334, p[3]=26500, p[4]=19169, p[5]=15724, p[6]=11478, p[7]=29358, p[8]=26962, p[9]=24464, p[10]=5705, p[11]=28145, p[12]=23281, p[13]=16827, p[14]=9961, p[15]=491, p[16]=2995, p[17]=11942, p[18]=4827, p[19]=5436, p[20]=32391, p[21]=14604, p[22]=3902, p[23]=153, p[24]=292, p[25]=12382, p[26]=17421, p[27]=18716, p[28]=19718, p[29]=19895, p[30]=5447, p[31]=21726,
c[0]=41, c[1]=18467, c[2]=6334, c[3]=26500, c[4]=19169, c[5]=15724, c[6]=11478, c[7]=29358, c[8]=26962, c[9]=24464, c[10]=5705, c[11]=28145, c[12]=23281, c[13]=16827, c[14]=9961, c[15]=491, c[16]=2995, c[17]=11942, c[18]=4827, c[19]=5436, c[20]=32391, c[21]=14604, c[22]=3902, c[23]=153, c[24]=292, c[25]=12382, c[26]=17421, c[27]=18716, c[28]=19718, c[29]=19895, c[30]=5447, c[31]=21726, p[0]=14771, p[1]=11538, p[2]=1869, p[3]=19912, p[4]=25667, p[5]=26299, p[6]=17035, p[7]=9894, p[8]=28703, p[9]=23811, p[10]=31322, p[11]=30333, p[12]=17673, p[13]=4664, p[14]=15141, p[15]=7711, p[16]=28253, p[17]=6868, p[18]=25547, p[19]=27644, p[20]=32662, p[21]=32757, p[22]=20037, p[23]=12859, p[24]=8723, p[25]=9741, p[26]=27529, p[27]=778, p[28]=12316, p[29]=3035, p[30]=22190, p[31]=1842, c[0]=14771, c[1]=11538, c[2]=1869, c[3]=19912, c[4]=25667, c[5]=26299, c[6]=17035, c[7]=9894, c[8]=28703, c[9]=23811, c[10]=31322, c[11]=30333, c[12]=17673, c[13]=4664, c[14]=15141, c[15]=7711, c[16]=28253, c[17]=6868, c[18]=25547, c[19]=27644, c[20]=32662, c[21]=32757, c[22]=20037, c[23]=12859, c[24]=8723, c[25]=9741, c[26]=27529, c[27]=778, c[28]=12316, c[29]=3035, c[30]=22190, #

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值