《用多线程同步方法解决生产者消费者问题 .docx》由会员分享,可在线阅读,更多相关《用多线程同步方法解决生产者消费者问题 .docx(12页珍藏版)》请在金锄头文库上搜索。
1、1. 需求分析11.1课程设计题目 11.2课程设计任务11.3课程设计原理 11.4课程设计要求11.5实验环境 12. 概要设计22.1课程设计方案概述22.2课程设计流程图 23. 详细设计 33.1主程序模块 33.2 生产者程序模块43.3消费者程序模块 54. 调试中遇到的问题及解决方案55. 运行结果66. 实验小结7参考文献7附录:源程序清单 7武汉理工大学华夏学院操作系统原理课程设计报告1. 需求分析1.1课程设计题目用多线程同步方法解决生产者-消费者问题1.2课程设计任务(1) 每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前指针位置和生产者/消
2、费者线程的标识符。(2) 生产者和消费者各有两个以上。(3) 多个生产者或多个消费者之间须共享对緩冲区进行操作的函数代码。1.3课程设计原理生产者和消费者问题是从操作系统中的许多实际同步问题中抽象岀来的具有代表性的问题,它反映了操作系统中典型的同步例子,生产者进程 (进程由多个线程组成)生产信息, 消费者进程使用信息,由于生产者和消费者彼此独立,且运行速度不确定,所以很可能出现生产者已产生了信息而消费者却没有来得及接受信息这种情兄为此,需要引入由一个或者若干个存储单元组成的临时存储区(即缓冲区),以便存放生产者所产生的信息,解决平滑进程间由于速度不确定所带来的问题。1.4课程设计要求(1) 有
3、界缓冲区内设有20个存储单元,放入/取岀的数据项设定为120这20个整型数。(2) 每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前指针位置和生产者/消费者线程的标识符。(3) 生产者和消费者各有两个以上。(4) 多个生产者或多个消费者之间须共享対緩冲区进行操作的函数代码。1.5实验环境系统平台:LINUX开发语言:C开发工具:PC机一台2. 概要设计2.1课程设计方案概述作为有界缓冲区,纟爰冲区为 0时,代表该本设计中设置一个长度为20的一维数组buff20緩冲区内没有产品,buffi=i+1 表示有产品,产品为i+1 o设置3个同步信号灯:一个说明空缓冲区的数目
4、,用empty表示,其初值为有界缓冲区的大小20 ;另一个说明满缓冲区(即产品)的数目,用full表示,其初值为00由于緩冲区是临界资源,必须互斥使用,所以还设置了一个互斥信号灯mutex ,其初值为1。用这3个信号灯有效控制多个生产者线程和多个消费者线程的同步准确的运行。Main ()函数中调用函数sem_init()对信号灯进行初始化;利用 for语句循环创建5个producer(生产者)分离线程和 5个consumed消费者)分离线程;Producer线程通过调用函数 sem_wait(&empty)判断是否有空缓冲区。若无,则阻塞当前线程,若有则调用函数sem_wait(&mutex)
5、等待对临界资源的操作权,当 mntex为1时,便获得临界资源的操作权,可 将产品放入缓冲区,及时输出缓冲区里的内容。然后依次调用函数sem_post(&mutex)和sem_post(&full)来释放緩冲区操作权和增加满缓冲区信号量的值; Consumer线程通过调用函 数sem_wait(&full) 判断是否有满緩冲区若无,则阻塞当前线程,若有则调用函数 sem_wait(&mutex)等待対临界资源的操作权,当 mntex为1时,便获得临界资源的操作权,可 从满缓冲区中取出产品消费,并及时输出缓冲区里的内容。然后依次调用函数sem_post(&mutex) 和sem_post(&emp
6、tyl)来释放缓冲区操作权和增加空满缓冲区信号量的值。Producer和Consumer线程中均用缓冲区指针b指出当前是对哪一个缓冲区进行放入/取出操作;并调用pthread_self()函数来显示其自身的标识符。2.2课程设计流程图设计中主要有三个模块,首先从主程序中进入,完成初始化及创建好生产者和消费 者线程后,进入生产者或消费者模块,具体流程见程序设计流程图如图1所示:武汉理工大学华夏学院操作系统原理课程设计报告3生产者消费者图1程序设计流程图3. 详细设计for语句循环创建 3个3.1主程序模块主程序中利用函数sem_init()对信号灯进行初始化;利用producer生产者)分离线程
7、和3个consume*消费者)分离线程,程序段如下:int main(void)武汉理工大学华夏学院操作系统原理课程设计报告 inti;initbuff();for(i=0;i5;i+)(pthread_create(&id 1 i,NULL,(void *)producer,(&i);) 创建生产者线程for(i=0;i5;i+)(pthread_create(&id2i,NULL,(void consumer,(&i);创建消费者线程for(i=0;i5;i+)( pthreadjoin(id1 i,NULL);pthreadjoin(id2i,NULL);exit(O); 等待生产者线程
8、,消费者线程,结束主线程3.2 生产者程序模块Producer线程通过调用函数 sem_wait(&empty)判断是否有空缓冲区。若无,则阻塞当前线程,若有则调用函数sem_wait(&mutex)等待对临界资源的操作权,当 mntex为及时输出缓冲区里的内容;并1时,便获得临界资源的操作权,可将产品放入缓冲区,用指针b指出当前是对哪一个緩冲区进行放入/取出操作,且调用 pthread_self()函数来显示其自身的标识符。然后依次调用函数sem_post(&mutex)和 sem_post(&full)来释放緩冲区操作权和增加满緩冲区信号量的值,程序段如下:void producer()
9、/生产者(int pid=O;intj.k;pid=pthread_self();/获得生产者标识符while(1)for(j=0;j5;j+)if(pid=id10D k=j+1; )sem_wait(&empty);/P操作,判断缓冲区是否有空位置sem_wait(&mutex);/P操作,获得对临界资源的操作权(buffb=p%21;printf(producer %d produce:%dn,k,p%21);printbuff();b+; p+;else p+;操作,释放临界资源sem_post(&mutex); /Vsem_post(&full); /V操作,满纟套冲区信号灯加sle
10、ep(4); 3.3消费者程序模块Consumer线程调用调用函数 sem_wait(&full)判断是否有满纟爰冲区。若无,则阻塞 当前线程,若有则调用函数sem_wait(&mutex)等待对临界资源的操作权,当 mntex为1 时,便获得临界资源的操作权,可从满缓冲区中取出产品消费,并及时输出缓冲区里的内容,并用指针b指出当前是对哪一个缓冲区进行放入/取出操作,且调用pthread_self()函数来显示其自身的标识符。然后依次调用函数sem_post(&mutex)和sem_post(&emptyl) 来释放纟爰冲区操作权和増加空满缓冲区信号量的值,程序段如下:void consume
11、r() /消费者(int cid=0;cid=pthread_self();获得消费者标识符while(1)( for(j=0;j/whj1 produce:1 buff arc:1 02 produce:2 buff are:1 23 produce:3 buff are:1 24 produce:4 buff are:1 25 produce:5 buff are:1 21 consuoke : 5 buff are:1 22 consune : 4 buff are:1 23 consuate : 3 buff are:1 24 consuoM? :2 buff are:1 05 consune:1 buff arc:0 01 produce:6 buff are:6 02 produce:? buff are:6 73 produce:8 buff are:6 74 produce:9 buff are75 produce:10whj6. 实