《操作系统课程设计用多进程同步方法解决生产者消费者问题.pdf》由会员分享,可在线阅读,更多相关《操作系统课程设计用多进程同步方法解决生产者消费者问题.pdf(19页珍藏版)》请在三一文库上搜索。
1、操作系统课程设计 用多进程同步方法解决生产者- 消费者问题 系别:计科系 专业: 计 算 机 科 学 与 技 术 班级:04 级4 班 学号:04101010608 姓名:苏德洪 时间:2006-7-72006-7-14 目录 一、题目: . 3 二、设计目的: 3 三、总体设计思想概述: 3 四、说明: . 3 五、设计要求: 3 六、设计方案: 3 七、流程图: . 5 八、运行结果 . 7 九、源程序 . 11 十、总结 . 18 十一、参考文献 20 一、题目: 用多进程同步方法解决生产者- 消费者问题。 二、设计目的: 通过研究 Linux 的进程机制和信号量实现生产者消费者问题的并
2、发控制。 三、总体设计思想概述: 1、 生产者消费者问题是一种同步问题的抽象描述。 2、 计算机系统中的每个进程都可以消费或生产某类资源。当系统中某一进程使用某一 资源时,可以看作是消耗,且该进程称为消费者。 3、 而当某个进程释放资源时,则它就相当一个生产者。 四、说明: 有界缓冲区内设有20 个存储单元 , 放入 / 取出的数据项设定为1-20 这 20 个整型数。 五、设计要求: 1、每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前 指针位置和生产者/ 消费者线程的标识符。 2、生产者和消费者各有两个以上。 3、多个生产者或多个消费者之间须有共享对缓冲区进行操
3、作的函数代码。 六、设计方案: 通过一个有界缓冲区(用数组来实现,类似循环队列)把生产者和消费者联系起来。假定 生产者和消费者的优先级是相同的,只要缓冲区未满,生产者就可以生产产品并将产品送入 缓冲区。类似地,只要缓冲区未空,消费者就可以从缓冲区中去走产品并消费它。 应该禁止生产者向满的缓冲区送入产品,同时也应该禁止消费者从空的缓冲区中取出产 品,这一机制有生产者线程和消费者线程之间的互斥关系来实现。 为解决生产者/消费者问题,应该设置两个资源信号量,其中一个表示空缓冲区的数目, 用 g_hFullSemaphore表示,其初始值为有界缓冲区的大小SIZE_OF_BUFFER;另一 个表示缓冲
4、区中产品的数目,用g_hEmptySemaphore表示,其初始值为0。另外,由于有 界缓冲区是一个临界资源,必须互斥使用,所以还需要再设置一个互斥信号量g_hMutex , 起初值为1。 在生产者 /消费者问题中,信号量实现两种功能。首先,它是生产产品和消费产品的计 数器,计数器的初始值是可利用的资源数目(有界缓冲区的长度)。其次,它是确保产品的生 产者和消费者之间动作同步的同步器。 生产者要生产一个产品时,首先对资源信号量g_hFullSemaphore和互斥信号量 g_hMutex进行 P 操作,申请资源。如果可以通过的话,就生产一个产品,并把产品送入缓 冲区。然后对互斥信号量g_hMu
5、tex和资源信号量g_hEmptySemaphore进行 V 操作,释 放资源。 消费者要消费一个产品时,首先对资源信号量g_hEmptySemaphore和互斥信号量 g_hMutex进行 P 操作,申请资源。 如果可以通过的话,就从缓冲区取出一个产品并消费掉。 然后对互斥信号量g_hMutex和资源信号量g_hFullSemaphore进行 V 操作,释放资源。 如果缓冲区中已经没有可用资源,就把申请资源的进程添加到等待队列的队尾。如果有 一个资源被释放,在等待队列中的第一个进程被唤醒并取得这个资源的使用权。 七、流程图: 1、生产者 2、消费者 八、运行结果 1、截图一: 2、截图二:
6、3、截图三: 4、截图四: 九、源程序 /本程序于2005.12.25 在 VC+6.0 下运行通过 /系统环境: Windows XP #include #include const unsigned short SIZE_OF_BUFFER = 20;/ 有界缓冲区长度 int g_bufferSIZE_OF_BUFFER;/开辟缓冲区,用数组表示,可以看成是一个循环队列 unsigned short ProductID = 0;/ 新生产出来的产品的产品号 unsigned short ConsumeID = 0;/ 被消耗的产品的产品号 unsigned short in = 0;/
7、产品进缓冲区时的缓冲区下标,用于记录生产者的指针位置 unsigned short out = 0;/ 产品出缓冲区时的缓冲区下标,用于记录消费者的指针位置 bool g_continue = 1;/ 控制程序运行:1表示继续运行,0 表示停止运行 HANDLE g_hMutex;/线程间的互斥信号量 HANDLE g_hFullSemaphore;/ 资源信号量:缓冲区满 HANDLE g_hEmptySemaphore;/ 资源信号量:缓冲区空 DWORD WINAPI Producer(LPVOID);/生产者线程 DWORD WINAPI Consumer(LPVOID);/消费者线程
8、 const unsigned short PRODUCERS_COUNT=4;/ 生产者的个数 const unsigned short CONSUMERS_COUNT=3;/消费者的个数 const unsigned short THREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT;/ 总线程数 HANDLE hThreadsPRODUCERS_COUNT;/各线程的handle DWORD producerIDCONSUMERS_COUNT;/生产者线程的标识符 DWORD consumerIDTHREADS_COUNT;/消费者线程的标识符 /*-
9、生产一个产品开始-*/ /生产一个产品,输出其ID 号 void Produce() std:coutstd:endl; std:cerr“ 生产一个产品: “+ProductID; std:coutstd:endl; /*-生产一个产品结束-*/ /*-把新生产的产品放入缓冲区开始-*/ /把新生产的产品放入缓冲区 void Append() std:cerr“ 把生产的产品送入缓冲区“; g_bufferin=ProductID; in=(in+1)%SIZE_OF_BUFFER; std:cerrstd:endl; std:cout“ 缓冲区产品生产者 /消费者 “std:endl; /
10、新产品放入缓冲区后,输出缓冲区当前的状态 for(int i=0;iSIZE_OF_BUFFER;+i) /输出缓冲区下标 if (i10) std:couti“ “g_bufferi; else std:couti“ “g_bufferi; if(i=in) if(g_bufferi10) std:cout“ “; else std:cout“ “; std:cout“ - 生产者 “;/输出生产者的指针位置 if(i=out) if(g_bufferi10) std:cout“ “; else std:cout“ “; std:cout“ - 消费者 “;/输出消费者的指针位置 std:c
11、outstd:endl; /*-把新生产的产品放入缓冲区结束-*/ /*-消费一个产品开始-*/ void Consume()/ 消费一个产品 std:coutstd:endl; std:cerr“ 消费一个产品: “ConsumeID; std:coutstd:endl; /*-消费一个产品结束-*/ /*-从缓冲区中取出一个产品开始-*/ /从缓冲区中取出一个产品 void Take() std:coutstd:endl; std:cerr“ 从缓冲区取出一个产品“; ConsumeID=g_bufferout; out=(out+1)%SIZE_OF_BUFFER; std:cerrst
12、d:endl; std:coutstd:endl; std:cout“ 缓冲区产品生产者 /消费者 “std:endl; /取出一个产品后,输出缓冲区当前的状态 for(int i=0;iSIZE_OF_BUFFER;+i) /输出缓冲区下标 if(i10) std:couti“ “g_bufferi; else std:couti“ “g_bufferi; if(i=in) if(g_bufferi10) std:cout“ “; else std:cout“ “; std:cout“ - 生产者 “;/输出生产者的指针位置 if(i=out) if(g_bufferi10) std:cou
13、t“ “; else std:cout“ “; std:cout“ - 消费者 “;/输出消费者的指针位置 std:coutstd:endl; /*-从缓冲区中取出一个产品结束-*/ /*-生产者线程开始-*/ /生产者线程 DWORD WINAPI Producer(LPVOID lpPara) while(g_continue) /资源信号量的P 操作 WaitForSingleObject(g_hFullSemaphore,INFINITE); /互斥信号量的P 操作 WaitForSingleObject(g_hMutex,INFINITE); /生产一个产品 Produce(); /
14、把新生产的产品放入缓冲区 Append(); Sleep(2000); /互斥信号量的V 操作 ReleaseMutex(g_hMutex); /资源信号量的V 操作 ReleaseSemaphore(g_hEmptySemaphore,1,NULL); return 0; /*-生产者线程结束-*/ /*-消费者线程开始-*/ /消费者线程 DWORD WINAPI Consumer(LPVOID lpPara) while(g_continue) /资源信号量的P 操作 WaitForSingleObject(g_hEmptySemaphore,INFINITE); /互斥信号量的P 操作
15、 WaitForSingleObject(g_hMutex,INFINITE); /从缓冲区中取出一个产品 Take(); /消费一个产品 Consume(); Sleep(2000); /互斥信号量的V 操作 ReleaseMutex(g_hMutex); /资源信号量的V 操作 ReleaseSemaphore(g_hFullSemaphore,1,NULL); return 0; /*-消费者线程结束-*/ /*-创建生产者线程开始-*/ void createPT()/ 创建生产者线程 for(int i=0;iPRODUCERS_COUNT;+i) hThreadsi=CreateT
16、hread(NULL,0,Producer,NULL,0, if(hThreadsi=NULL) g_continue=0; /*-创建生产者线程结束-*/ /*-创建消费者线程开始-*/ void createCT()/ 创建消费者线程 for (int j=0;jCONSUMERS_COUNT;+j) hThreadsPRODUCERS_COUNT+j=CreateThread(NULL,0,Consumer,NULL,0, if (hThreadsj=NULL) g_continue=0; /*-创建消费者线程结束-*/ /*-主函数开始 -*/ void main() /显示程序提示信
17、息 info(); /创建互斥信号量 g_hMutex=CreateMutex(NULL,FALSE,NULL); /创建资源信号量 g_hFullSemaphore=CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1, NULL); g_hEmptySemaphore=CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL); /创建生产者线程 createPT(); /创建消费者线程 createCT(); /不按回车键的话程序会一直运行下去 while(g_continue) /按回车键终止程序 if(getchar() g_continue = 0; /*-主函数结束 -*/ 十、总结 本课程设计是学生学习完计算机操作系统课程后,进行的一次全面的综合训练,通 过课程设计, 让学生更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重 要算法的理解,加强学生的动手能力。 十一、参考文献 【1】汤子瀛等 .计算机操作系统. 西安电子科技大学出版社.2004 年 5 月 【2】付国瑜杨武周敏 . 计算机操作系统原理及应用上机实验指导. 重庆工学院计算机 学院 .2005 年 1 月.
链接地址:https://www.31doc.com/p-5522577.html