//让其他消费者或生产者使用
printf(\消费者d: 我需要buf[%d]=%s\\n\,i, ptr, thing[g_buf.product[ptr]]); //消费完毕,并释放一个缓冲
printf(\消费者d: 我消费完毕%s\\n\, i,thing[g_buf.product[ptr]]); V(Mutex); V(Empty);
Sleep(rate*rand()+110); }
return 0; }
/**************** 生产者线程
********************************/ DWORD WINAPI Producer(LPVOID para) {
int i = *(int *)para - CONSUMER_NUM; int ptr;
int data; //产品 int j=0;
while(j++<4) {
data=rand()%8;
printf(\生产者d: 生产出: %s!\\n\,i,thing[data]); //等待存放空间 P(Empty);
//有地方,先锁住缓冲区 P(Mutex);
//记录消费的物品 ptr=g_buf.end; //再移动缓冲区指针
g_buf.end =(g_buf.end+1)%BUFFER_NUM; printf(\生产者d: 放到缓冲区 buf[%d]=%s\\n\,i,ptr,thing[data]); g_buf.product[ptr]=data; //放好了完毕,释放一个产品 //让其他消费者或生产者使用 V(Mutex); V(Full);
Sleep(rate/2*rand()+110); }
return 0;
11
}
int main(int argc,char *argv[]) {
//线程技术,前面为消费者线程,后面为生产者线程
HANDLE hThread[CONSUMER_NUM+PRODUCER_NUM]; // 线程计数
srand(time(NULL)); rand();
DWORD tid; int i=0;
//初始化信号量
Mutex=CreateSemaphore(NULL,1,1,\); Empty=CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, \);
Full=CreateSemaphore(NULL,0,BUFFER_NUM,\); if(!Empty||!Full||!Mutex) {
printf(\);
return -1; }
int totalThreads=CONSUMER_NUM+PRODUCER_NUM; //开启消费者线程
printf(\先请消费者上席!\\n\); for(i=0;i hThread[i]=CreateThread(NULL, 0, Consumer, &i,0,&tid); if(hThread[i])WaitForSingleObject(hThread[i],10); } printf(\生产者就位!\\n\); for(;i hThread[i]=CreateThread(NULL,0,Producer,&i,0,&tid); if(hThread[i])WaitForSingleObject(hThread[i],10); } //生产者和消费者的执行 WaitForMultipleObjects(totalThreads,hThread,TRUE,INFINITE); return 0; } 12 6.2、编译及运行结果 在程序中设置了两个消费者,三个生产者,为便于描述出生产-消费的过程,我用食物代表被缓冲区消费的资源。在实验结果中我们可以看到几个生产者生产的食物放在缓冲区中,消费者需求的话就去缓冲区去取。在同一个时间点上不必生产者生产一个消费者就消费一个,消费者某个时间消费的资源有可能是上一个生产者所生产的。由于按题目要求设置的缓冲区为20,所以缓冲区没有溢出到等待消费者消费的情况。 图三 运行结果 七.课程设计总结 本次课程设计通过模拟计算机操作系统中经典的“生产者—消费者问题”,巩固了我在操作系统原理课上所学的知识,加深了对操作系统中进程同步和互斥等问题,完成了多进程同步方法解决生产者-消费者问题全部过程,结果满足设计要求。 设计过程中遇到不少困难,在反复研究老师的PPT及课本的原理后才逐 13 渐明晰怎样将代码实现,虽然这学期学过Java,但java不是很熟悉,因此还是选择C++语言。以前学习C++没有深入了解到线程这个概念,在学习Java的时候才知道有专门的线程类。所以我在网上也参考了其他人用C++编写尤其是关于多进程程序的设计实现。在代码的实现过程中,我是主要定义了两个函数 DWORD WINAPI Consumer(LPVOID para) 和 DWORD WINAPI Producer(LPVOID para),在这两个函数中实现PV操作。 通过本次设计,我较好地掌握了通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制全过程,尤其是对多进程程序设计方法有了更深的理解,开拓了思路,锻炼了实践动手能手。但是我觉得课程设计的时间有点短,中间又夹杂着好几场考试,所以没能做出界面以便于直观的观察出详细过程,只是用代码实现了要描述的功能且达到了要求,所以改进的空间还比较大。 参考文献 [1]汤子瀛.《计算机操作系统》(修订版).西安电子科技大学出版社,2001。 [2]计算机操作系统教程.孙钟秀等编著.高等教育出版社,2010年8月出版 [3]数据结构教程.李春葆等编著 清华大学出版社.2009年4月 [4]面向对象程序设计与Visual C++6.0教程 陈天华编著 清华大学出版社.2009年7月 14