用多线程同步方法解决生产者_第1页
用多线程同步方法解决生产者_第2页
用多线程同步方法解决生产者_第3页
用多线程同步方法解决生产者_第4页
用多线程同步方法解决生产者_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 TOC o 1-5 h z HYPERLINK l bookmark7 o Current Document 需求分析1 HYPERLINK l bookmark11 o Current Document 1.1课程设计题目1 HYPERLINK l bookmark14 o Current Document 1.2课程设计任务1 HYPERLINK l bookmark20 o Current Document 1.3课程设计原理1 HYPERLINK l bookmark23 o Current Document 1.4课程设计要求1 HYPERLINK l bookmark30 o C

2、urrent Document 1.5实验环境1 HYPERLINK l bookmark33 o Current Document 概要设计2 HYPERLINK l bookmark37 o Current Document 2.1课程设计方案概述2 HYPERLINK l bookmark40 o Current Document 2.2课程设计流程图2 HYPERLINK l bookmark43 o Current Document 详细设计3 HYPERLINK l bookmark47 o Current Document 3.1主程序模块3 HYPERLINK l bookma

3、rk50 o Current Document 3.2 生产者程序模块4 HYPERLINK l bookmark53 o Current Document 3.3消费者程序模块5 HYPERLINK l bookmark56 o Current Document 调试中遇到的问题及解决方案5 HYPERLINK l bookmark63 o Current Document 运行结果6 HYPERLINK l bookmark67 o Current Document 实验小结7 HYPERLINK l bookmark70 o Current Document 参考文献7 HYPERLIN

4、K l bookmark78 o Current Document 附录:源程序清单7需求分析1.1课程设计题目用多线程同步方法解决生产者一消费者问题1.2课程设计任务每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前指针位置和生产者/消费者线程的标识符。生产者和消费者各有两个以上。多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。1.3课程设计原理生产者和消费者问题是从操作系统中的许多实际同步问题中抽象出来的具有代表性的问题,它反映了操作系统中典型的同步例子,生产者进程(进程由多个线程组成)生产信息, 消费者进程使用信息,由于生产者和消费者彼此独立,且运行

5、速度不确定,所以很可能出现生产 者已产生了信息而消费者却没有来得及接受信息这种情况。为此,需要引入由一个或者若干个存 储单元组成的临时存储区(即缓冲区),以便存放生产者所产生的信息,解决平滑进程间由于速 度不确定所带来的问题。1.4课程设计要求有界缓冲区内设有20个存储单元,放入/取出的数据项设定为120这20个整型数。每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前指针位置和生产者/消费者线程的标识符。生产者和消费者各有两个以上。多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。1.5实验环境系统平台:LINUX开发语言:C开发工具:PC机一台概要设计2

6、.1课程设计方案概述本设计中设置一个长度为20的一维数组buff20作为有界缓冲区,缓冲区为0时,代表该 缓冲区内没有产品,buffi=i+1表示有产品,产品为i+1。设置3个同步信号灯:一个说明空缓冲区的数目,用empty表示,其初值为有界缓冲区的大 小20 ;另一个说明满缓冲区(即产品)的数目,用full表示,其初值为0。由于缓冲区是临界 资源,必须互斥使用,所以还设置了一个互斥信号灯mutex,其初值为1。用这3个信号灯有效 控制多个生产者线程和多个消费者线程的同步准确的运行。Main()函数中调用函数sem_init()对信号灯进行初始化;利用for语句循环创建5个 producer(

7、生产者)分离线程和5个consumer(消费者)分离线程;Producer线程通过调用函数 sem_wait(&empty)判断是否有空缓冲区。若无,则阻塞当前线程,若有则调用函数 sem_wait(&mutex)等待对临界资源的操作权,当mntex为1时,便获得临界资源的操作权,可 将产品放入缓冲区,及时输出缓冲区里的内容。然后依次调用函数sem_post(&mutex)和sem_post(&full)来释放缓冲区操作权和增加满缓冲区信号量的值;Consumer线程通过调用函 数sem_wait(&full)判断是否有满缓冲区。若无,则阻塞当前线程,若有则调用函数 sem_wait(&mut

8、ex)等待对临界资源的操作权,当mntex为1时,便获得临界资源的操作权,可 从满缓冲区中取出产品消费,并及时输出缓冲区里的内容。然后依次调用函数sem_post(&mutex) 和sem_post(&emptyl)来释放缓冲区操作权和增加空满缓冲区信号量的值。Producer和Consumer线程中均用缓冲区指针b指出当前是对哪一个缓冲区进行放入/取出操作;并调用 pthread_self()函数来显示其自身的标识符。2.2课程设计流程图设计中主要有三个模块,首先从主程序中进入,完成初始化及创建好生产者和消费 者线程后,进入生产者或消费者模块,具体流程见程序设计流程图如图1所示:生产者消费者

9、图1程序设计流程图详细设计3.1主程序模块主程序中利用函数 sem_init()对信号灯进行初始化;利用 for语句循环创建3个 producer(生产者)分离线程和3个consumer(消费者)分离线程,程序段如下:int main(void)( int i;initbuff();for(i=0;i5;i+)pthread_create(&id1i,NULL,(void *)producer,(&i);创建生产者线程for(i=0;i5;i+)pthread_create(&id2i,NULL,(void *)consumer,(&i);创建消费者线程for(i=0;i5;i+) pthre

10、ad_join(id1i,NULL);pthread_join(id2i,NULL); exit(0); /等待生产者线程,消费者线程,结束主线程3.2生产者程序模块Producer线程通过调用函数sem_wait(&empty)判断是否有空缓冲区。若无,则阻塞 当前线程,若有则调用函数sem_wait(&mutex)等待对临界资源的操作权,当mntex为 1时,便获得临界资源的操作权,可将产品放入缓冲区,及时输出缓冲区里的内容;并 用指针b指出当前是对哪一个缓冲区进行放入/取出操作,且调用pthread_self()函数来 显示其自身的标识符。然后依次调用函数sem_post(&mutex)

11、和 sem_post(&full)来释放 缓冲区操作权和增加满缓冲区信号量的值,程序段如下: void producer()/生产者 int pid=0;int j,k;pid=pthread_self();/获得生产者标识符while(1) for(j=0;j5;j+) if(pid=id1j) k=j+1; sem_wait(&empty);/P操作,判断缓冲区是否有空位置sem_wait(&mutex);/P操作,获得对临界资源的操作权if(p%21!=0) buffb=p%21;printf(producer %d produce:%dn”,k,p%21);printbuff();b+

12、;p+; else p+;sem_post(&mutex); /V操作,释放临界资源sem_post(&full);/V操作,满缓冲区信号灯加1sleep(4); 3.3消费者程序模块Consumer线程调用调用函数sem_wait(&full)判断是否有满缓冲区。若无,则阻塞 当前线程,若有则调用函数sem_wait(&mutex)等待对临界资源的操作权,当mntex为1 时,便获得临界资源的操作权,可从满缓冲区中取出产品消费,并及时输出缓冲区里的 内容,并用指针b指出当前是对哪一个缓冲区进行放入/取出操作,且调用pthread_self() 函数来显示其自身的标识符。然后依次调用函数sem

13、_post(&mutex)和 sem_post(&emptyl) 来释放缓冲区操作权和增加空满缓冲区信号量的值,程序段如下:void consumer()/消费者 int cid=0;int j,k;cid=pthread_self();/获得消费者标识符while(1) for(j=0;j5;j+) if(cid=id2j) k=j+1; sem_wait(&full); /P操作,判断缓冲区是否已满sem_wait(&mutex);/P操作,获得对临界资源的操作权if(c%21!=0) c1=buffb-1;printf(consumer %d consume:%dn”,k,c1);buf

14、fb-1=0;printbuff();b;c+; else c+;sem_post(&mutex);/V操作,释放临界资源sem_post(&empty);/V操作,释放一个空位置sleep(6); 调试中遇到的问题及解决方案在调试过程中主要遇到三个问题:在设计刚完成的时候,我并没有用pid=pthread_self()和cid=pthread_self()来获 得生产者和消费者的标识符,所以运行的结果是生产者和消费者的标识符都是随机的,后 来问同学才找到这种调用方法。我想让生产者无限的生产,消费者无限的消费,所以就用了一个条件判断语句,判断 的条件是p%21!=0,而我写成了 p/21!=0

15、,所以运行的结果是生产者的生产是混乱的,没 有规律。刚开始我的运行结果还有一个问题就是生产者生产超过21的产品后,产品号不是1, 2等,而是 21,22,,后来检查后才发现 printf(producer %d produce:%dn,k,p%21) 中的产品号不是p%21,所以出现那种情况。运行结果显示结果如下:(部分运行结果)host jc 1 pt bread -o *hj ocal host . /whjproducec 1 produce:1datas i nbuff are:1 000Q0Q0000Q0Q0Q0Q00prcduccr2 produce:2Jatas inbuff a

16、re:1 200Q000000Q000Q0000producec3 produceddatas i nbuff are:1 230QQ00Q00QQ00QQ000prcduccr4 produce:4datas i nbuff are;1 234QQ00Q00QQ00QQ000producec5 produce:5datas i nbuff are:1 2345Q00Q0QQQ00QQ000consurttcr1 conUnc:5datas i nbuff are;1 234QQ00Q00QQ00QQ000consurtMic-2 conUrtKi:4datas i nbuff are:1 2

17、30QQ00Q00QQ00QQ000consurttcr3 conUtMi:3datas i nbuff are;1 200QQ00Q00QQ00QQ000consurtMic-4 conUrtKi:2datas i nbuff are:1 000QQ00Q00QQ00QQ00Qconsurttcr5 consurtMi: 1datas i nbuff are:0 Q00QQ00Q00QQ00QQ00Qproducc:-1 produce:datas i nbuff areifi Q00QQ00Q00QQ00QQ00Qprcduccr2 produce:7datas i nbuff are:6

18、 700QQ00Q00QQ00QQ00Qproducc:-3 produceddatas i nbuff areifi 7&0QQ00Q00QQ00QQ00Qprcduccr4 produce:9datas i nbuff7Sg0Q000000Q000Q00Qproducce- 5 produce: 106.实验小结这次课程设计主要针对的是操作系统中的经典问题即:生产者一一消费者问题使用多线 程控制,刚拿到设计题目时心里其实挺没底的,因为之前我对线程不是很了解,不过幸好老 师上课的时候给了我们一个关于Linux多线程编程的文档,里面详细的介绍了线程的一些 基本命令,所以我在这次设计中基本上都用

19、的是文档里的命令。从这次课程设计中,我对线程的概念以及一些命令都有了一定的理解和掌握,并且也知 道了它与进程之间的区别,除此之外,通过这次课程设计让我对操作系统中的经典问题,生 产者一一消费者问题有了更深的理解,在做设计的过程中,也对上课的内容加深了理解并进 行了巩固。参考文献庞丽萍.操作系统原理.华中科技大学出版社.2009年1月。蒋静徐志伟.操作系统原理技术与编程M.北京:机械工业出版社,2004张红光 李福才.UNIX操作系统。机械工业出版社。2006年1月汤子瀛等.计算机操作系统.西安电子科技大学出版社.2001年5月付国瑜杨武周敏.计算机操作系统原理及应用上机实验指导.重庆工学院计算

20、机学 院.2005年1月.附录:源程序清单#include #include#include#includeint buff20 = 0; /有界缓冲区定义int b=0;/缓冲区的输出指针int p=1;int c=1;int c1=0;/消费数据变量sem_t full;/缓冲区的数量信号灯sem_t empty;/缓冲区满信号灯sem_t mutex;/互斥信号灯pthread_t id15;pthread_t id25;void initbuff()/初始化信号灯 sem_init(&full,0,0);sem_init(&empty,0,20);sem_init(&mutex,0,1

21、); /初始化互斥信号灯void printbuff()/打印缓冲区 int j;printf(datas in buff are:);for(j=0;j20;j+)printf(%d ”,buffj);printf(n); void producer()/生产者 int pid=0;int j,k;pid=pthread_self();while(1) for(j=0;j5;j+) if(pid=id1j) k=j+1; sem_wait(&empty);sem_wait(&mutex);if(p%21!=0) buffb=p%21;printf(producer %d produce:%dn”,k,p%21);printbuff();b+;p+; else p+;sem_post(&mutex);sem_post(&full);sleep(4); void consumer()/消费者 int cid=0;int j,k;cid=pthread_self

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论