您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 用多进程同步方法演示“生产者-消费者”问题
**理工大学操作系统课程设计报告院(系):计算机工程学院专业:计算机科学与技术班级:计算111学生姓名:**学号:201107015题目:用多进程同步方法演示“生产者-消费者”问题起迄日期:2014.07.07-2014.07.18设计地点:现代教育中心101-103、主教学楼B505指导教师:王**2013—2014年度第2学期完成日期:2014年7月18日一、课程设计目的本次操作系统课程设计的主要任务是通过研究Linux的进程机制和信号量,实现生产者消费者问题的并发控制。实验中需要设置多个生产者和多个消费者,生产者和消费者对同一个缓冲区进行操作,互斥的访问缓冲区。本次课程设计的目的就是加深对多进程如何正确访问临界资源的理解,同时掌握条件变量在互斥访问时应该如何正确有效地使用。掌握生产者消费者问题的解决流程和方法,能够在此基础上解决现实中的具体问题。二、课程设计内容课程设计内容:1)生产者和消费者进程的数目不固定,可在程序界面上设置2)生产者和消费者进程的数目在程序界面上可调,在运行时可随时单个增加与减少生产者与消费者3)生产者的生产速度与消费者的消费速度均可在程序界面调节,在运行中,该值调整后立即生效4)生产者生产的产品由随机函数决定5)多个生产者或多个消费者之间必须有共享对缓冲区进行操作的函数代码6)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、当前生产者与消费者的指针位置,以及生产者和消费者线程标识符7)采用可视化界面,可在运行过程中随时暂停,查看当前生产者、消费者以及有界缓冲区的状态三、系统分析与设计1、系统分析1.1功能需求:生产者与消费者需要对缓冲池互斥操作,其中生产者和消费者的数目可以任意改变。生产者和消费者的速度也要随机的进行修改。可以查看当前生产者和消费者以及有界缓冲区的状态。1.2数据需求:本次试验生产者和消费者的数量要动态的增加、减少,还有缓冲区的产品数,以及生产、消费产品的指针。rear:生产者指针;front:消费者指针;size:产品数;CONSUME_TIME:消费者速度;PRODUCE_TIME:生产者速度;mutex:对缓冲区互斥操作的锁;empty_cond:缓冲区空的条件变量;full_cond:缓冲区满的条件变量。2、系统设计:3、模块设计:函数调用关系:设置生产速度删除消费者删除生产者缓冲池信息添加消费者主程序添加生产者设置消费速度voidinit_list()voidon_changed()voidcreate_pthread_producer()voidcreate_pthread_consumer()voidremove_pthread_producer()voidremove_pthread_producer()voidconsumer_time()voidproduce_time()voidshow_pool_fun()main()void*producer()void*consumer()voidadd_to_list()生产者流程图:是否申请空缓冲区信号量size=BUFFER_LENGTH缓冲区已满,线程阻塞rear=rear+1buffer[rear]=rand()%BUFFER_LENGTH;打印缓冲区状态size=size+1释放缓冲区开始结束消费者流程图:四、系统测试与调试分析1、系统测试(1)因为当生产者在缓冲区满了以后自动阻塞,所以生产者阻塞是否正常。测试说明测试名称用多进程同步方法演示“生产者-消费者”问题测试目的验证生产者阻塞测试技术单元测试测试方法黑盒测试法测试用例测试内容添加生产者,当生产者生产满缓冲区后,消费者阻塞。测试数据添加5个生产者预期结果缓冲区开始增加产品,产品数达到20后5个消费者阻塞测试结果与预期相符是否申请空缓冲区信号量size=BUFFER_LENGTH缓冲区已满,线程阻塞rear=rear+1buffer[rear]=rand()%BUFFER_LENGTH;打印缓冲区状态size=size+1释放缓冲区开始结束(2)因为当生产者在缓冲区满了以后自动阻塞,需要消费者唤醒,所以需要测试唤醒的实现是否正常。测试说明测试名称用多进程同步方法演示“生产者-消费者”问题测试目的消费者唤醒生产者测试技术单元测试测试方法黑盒测试法测试用例测试内容消费者阻塞时,开始增加消费者,唤醒生产者测试数据添加5个生产者预期结果消费者消费缓冲区中的产品,从而唤醒生产者测试结果与预期相符(3)测试生产者和消费者的速度是否可以调节测试说明测试名称用多进程同步方法演示“生产者-消费者”问题测试目的调节生产者和消费者的速度测试技术单元测试测试方法黑盒测试法测试用例测试内容调节生产者和消费者速度测试数据默认是1s,生产者速度2s,消费者速度3s预期结果生产者和消费者的速度改变测试结果与预期相符2、调试分析:2.1调试过程中遇到的问题及解决方案:(1)删除一个正在执行的生产者或者消费者之后,其他的生产者和消费者都处于等待状态,导致整个程序处于忙等状态。解决方案:正在执行的线程为了访问临界资源而为其加上锁,但在访问过程中被外界取消,由于线程处于响应取消状态,且采用异步方式响应,并且在打开独占锁以前的运行路径上存在取消点,则该临界资源将永远处于锁定状态得不到释放,从而使得其他的线程也无法执行。外界取消操作是不可预见的,因此需要POSIX线程API中提供的一个pthread_cleanup_push()/pthread_cleanup_pop()函数对自动释放资源。(2)不能取消子线程。解决方案:由于子线程中存在一个while(1)死循环,线程处于无限循环中,且循环体内没有执行至取消点的必然路径,导致线程无法由外部其他线程的取消请求而终止。此时可以在循环体的必经路径上应该加入pthread_testcancel()调用。(3)被删除的生产者线程和消费者线程仍然后在执行一次。解决方案:这是因为取消点被放在了缓冲池操作函数先调用之后,所以线程被取消后仍会对缓冲池进行一次操作。此时,只需要在缓冲池操作函数调用之前添加一个pthread_testcancel()调用即可。五、用户手册1、使用平台是linux下gcc安装gcc、Gtk命令:apt-getinstallbuild-essential#安装gcc/g++/gdb/make等基本编程工具apt-getinstallgnome-core-devel#安装libgtk2.0-devlibglib2.0-dev等开发相关库文件apt-getinstallpkg-config#用于在编译GTK程序时自动找出头文件及库文件位置apt-getinstalldevhelp#安装devhelpGTK文档查看程序apt-getinstalllibglib2.0-doclibgtk2.0-doc#安装gtk/glib的API参考手册及其它帮助文档apt-getinstallgladelibglade2-dev#安装基于GTK的界面GTK是开发Gnome窗口的c/c++语言图形库apt-getinstalllibgtk2.0*,#gtk+2.0所需的所有文件统通下载安装完毕。2、操作步骤:第一步:添加生产者第二步:添加消费者第三步:显示缓冲池信息第四步:删除生产者第五步:删除消费者第六步:设置生产者和消费者的速度六、程序清单创建生产者线程:intcreate_pthread_producer(){charpthread_id[20]=;pthread_tproducer_id;pthread_create(&producer_id,NULL,producer,NULL);//创建线程函数调用sprintf(pthread_id,%lu,producer_id);add_to_list(list_producers,pthread_id);//将线程添加到线程列表return0;}创建消费者线程:intcreate_pthread_consumer(){charpthread_id[20]=;pthread_tconsumer_id;pthread_create(&consumer_id,NULL,consumer,NULL);//创建线程函数调用sprintf(pthread_id,%lu,consumer_id);add_to_list(list_consumers,pthread_id);//将线程添加到线程列表return0;}生产者函数:void*producer(void*arg){pthread_detach(pthread_self());//线程分离charinfo[50]=Poolisfull,producer;char*value=(char*)malloc(30);sprintf(value,%lu,pthread_self());strcat(info,value);strcat(info,iswaiting!);while(1){pthread_testcancel();//设置取消点pthread_cleanup_push(pthread_mutex_unlock,(void*)&mutex);//线程清理处理函数pthread_mutex_lock(&mutex);//对临界资源加锁while(size=BUFFER_LENGTH){add_to_list(list_pool,info);producer_wait=1;pthread_cond_wait(&full_cond,&mutex);//线程阻塞,并解锁producer_wait=0;}pthread_testcancel();//设置取消点operate_pool(1);//对缓冲池操作pthread_mutex_unlock(&mutex);//解锁pthread_cond_signal(&empty_cond);//唤醒消费者pthread_cleanup_pop(0);//线程清理处理函数pthread_testcancel();//设置取消点usleep(10);}}消费者函数:void*consumer(void*arg){pthread_detach(pthread_self());//线程分离charinfo[50]=Poolisempty,consumer;char*value=(char*)malloc(30);sprintf(value,%lu,pthread_self());strcat(info,value);strcat(info,iswaiting!);while(1){pthread_testcancel();//设置取消点pthread_cleanup_push(pthread_mutex_unlock,(void*)&mutex);//线程清理处理函数pthread_mutex_lock(&mutex);//对临界资源加锁while(size=0){add_to_list(list_pool,info);consumer_wait=1;pthread_cond_wait(&empty_cond,&mutex);//线程阻塞,并加锁consumer_wait=0;}pthread_testcancel();//设置取消点operate_pool(0);//对缓冲池操作pthread_mutex_unlock(&mutex);//解锁pthread_cond_signal(&full_cond);//唤醒生产者pthread_cleanup_pop(0);//线程清理处理函数pthread_testcancel();//设置取消点usleep(10);}}操作缓冲池函数:void*operate_pool(constinttype){charproduce[20]=;char*value=(char*)malloc(30);sprintf(value,%lu,pthread
本文标题:用多进程同步方法演示“生产者-消费者”问题
链接地址:https://www.777doc.com/doc-5624636 .html