操作系统实验报告生产者消费者问题_第1页
操作系统实验报告生产者消费者问题_第2页
操作系统实验报告生产者消费者问题_第3页
操作系统实验报告生产者消费者问题_第4页
操作系统实验报告生产者消费者问题_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

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

文档简介

1、 操作系统 课程设计报告书题目: 生产者-消费者问题 姓 名: 学 号: 专 业: 指导教师: 完成时间: 2013年 11月-2013 年 12月课程设计的任务和具体要求1、课程设计的任务:基于线程的生产者-消费者的合作问题 其中(生产者)从外设获取数据进行生产 另外(消费者)消费后进行输出,并存储输出结果。- 在Linux环境下使用POSIX库进行设计实现2、课程设计的具体要求:l 完成N个生产者和M个消费者线程之间的并发控制,N、M不低于30,数据发送和接收缓冲区尺寸不小于20个(每个产品占据一个)。l 其中生产者线程1、3、5、7、9生产的产品供所有奇数编号的消费者线程消费,只有所有奇

2、数编号的消费者线程都消费后,该产品才能从缓冲区中撤销。l 其中生产者线程2、4、6、8、10生产的产品所有偶数编号的消费者线程都可消费,任一偶数编号消费者线程消费该消息后,该产品都可从缓冲区中撤销。l 其中11-20号生产者线程生产的产品仅供对应编号的消费者线程消费。l 其他编号生产者线程生产的产品可由任意的消费者线程消费。l 每个生产线程生产30个消息后结束运行。如果一个消费者线程没有对应的生产者线程在运行后,也结束运行。所有生产者都停止生产后,如果消费者线程已经没有可供消费的产品,则也退出运行。 指导教师签字: 日期: 指导教师评语:成绩: 指导教师签字: 日期: 课程设计所需软件、硬件等

3、Windows 7系统 VM虚拟机并安装ubuntu系统软件:Vi编辑器 GCC4.41设计语言:C语言第1章 引言1.1 设计背景生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。1.2 设计目标以生

4、产者和消费者问题为例,学习Linux和Windows下进程通信、同步机制的具体实现方法,主要是信号量和共享内存。第2章 设计原理、函数说明设计原理:多进程是一种非常简洁的多任务操作方式。在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种烦琐的多任务工作方式。生产者-消费者方案是多进程应用程序开发中最常用的构造之一。因此困难也在于此。因为在一个应用程序中可以多次重复生产者-消费者行为,其代码也可以如此。设计中创建了Consumer 类,该类通过在一些多进程应用程序中促进代码重用以及简化代码调试和维护来解决这个问题。多进程应用

5、程序通常利用生产者-消费者编程方案,其中由生产者进程创建重复性作业,将其传递给作业队列,然后由消费者进程处理作业。多进程是一种使应用程序能同时处理多个操作的编程技术。通常有两种不同类型的多进程操作使用多个进程:适时事件,当作业必须在特定的时间或在特定的间隔内调度执行时;后台处理,当后台事件必须与当前执行流并行处理或执行时;适时事件的示例包括程序提醒、超时事件以及诸如轮询和刷新之类的重复性操作。后台处理的示例包括等待发送的包或等待处理的已接收的消息。生产者-消费者方案很适合于后台处理类别的情况。这些情况通常围绕一个作业“生产者”方和一个作业“消费者”方。当然,关于作业并行执行还有其它考虑事项。在

6、大多数情况下,对于使用同一资源的作业,应以FCFS的方式按顺序处理,这可以通过使用单进程的消费者轻松实现。通过使用这种方法,使用单个进程来访问单个资源,而不是用多个进程来访问单个资源。要启用标准消费者,当作业到来时创建一个作业队列来存储所有作业。生产者进程通过将新对象添加到消费者队列来交付这个要处理的新对象。然后消费者进程从队列取出每个对象,并依次处理。当队列为空时,消费者进入休眠。当新的对象添加到空队列时,消费者会醒来并处理该对象。函数说明:a. 主程序 (main):i. 创建信号量并进行初始化ii. 创建生产者、消费者线程,生产者执行void *product(),消费者执行void *

7、prochase()iii. 等待所有子进程的结束iv. 销毁所有线程b. 生产者方法 product() :这个函数是生产者进行的生产过程,为所有的生产者所共享。c. 消费者方法 prochase() :这个函数是消费者进行的生产过程,为所有的消费者所共享。第3章 程序详细设计3.1程序模块设计该实验主要分为三大模块:1. 主程序,创建并控制程序的流程,其中控制线程的活动以及信号量的操作,如图3-1-1所示;2.生产者模块:生产者对缓冲区的操作,如图3-1-2所示;3.消费者模块:消费者对缓冲区的操作,如图3-1-3所示。程序相关模块的流程图图3-1-1 主程序 生产者线程开始资源信号量P操

8、作互斥信号量P操作生产一个产品把产品送入缓冲区互斥信号量V操作资源信号量V操作等待队列中有消费者线程等待队列中有消费者线程线程自我阻塞添加到等待队列线程自我阻塞添加到等待队列未通过未通过通过通过唤醒对头的消费者线程唤醒对头的消费者线程生产者线程结束YYNN图3-1-2 生产者流程消费者线程开始资源信号量P操作互斥信号量P操作从缓冲区取出一个产品消费一个产品互斥信号量V操作资源信号量V操作等待队列中有生产者线程等待队列中有生产者线程线程自我阻塞添加到等待队列线程自我阻塞添加到等待队列未通过未通过通过通过唤醒对头的生产者线程唤醒对头的生产者线程消费者线程结束YYNN图3-1-3 消费者流程3.2程

9、序代码结构 通过分析,我们已经了解到了可以采用信号量来解决n个进程的临界区问题,这n个进程共享一个信号量mutex(mutual exclusion),并初始化为1。每个进程Pi的组织结构如下图。由于本系统我们研究的是有限缓冲区(Bounded-Buffer)的生产者消费者问题。而且根据初始条件可知,该缓冲区内有20个缓冲项,每个缓冲项存储一个整形数。信号量mutex提供了对缓冲池访问的互斥要求,并初始化为1。信号量empty和full分别用来表示空缓冲项和满缓冲项的数量。信号量empty初始化为20,而信号量full初始化为0;生产者进程和消费者进程的代码如图。注意生产者和消费者之间的对称性

10、可以这样来理解代码:生产者为消费者生产满缓冲项,或消费者为生产者生产空缓冲项。第4章 实验结果实验结果如图4-1截图所示:图4-1 实验结果截图第5章 实验总结 进程的同步与互斥是操作系统课程中非常重要的一部分内容。通过本次课程设计,我不仅学会了使用信号量机制解决有限缓冲区的生产者消费者问题,而且对Linux系统下多线程编程有了更深入的了解。虽然实验以前我已经对信号量机制解决进程间同步问题的原理有了很清楚的认识,但是此次课程设计中仍然遇到了很多问题,如Linux系统下各种系统调用以及函数的各种参数,都花费了我很多时间去网上看各种资料虽然Linux系统中可以很方便的阅读源代码以及使用man命令进

11、行相应指令的查看,但是全英文的资料让人看了还是有点不懂,看来还要多多加强计算机专业英语的学习,以后便可以在Linux系统中查看各种帮助文件。另一个问题就是在编译的时候遇到的,刚开始用gcc o 多对多 多对多.c 进行编译的时候总是提示出错,后来查了相关资料才知道pthread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a,所以在使用pthread_create()等函数时,需要链接该库才能编译通过。以前再用Windows IDE进行编程的时候基本上不会遇到这样的问题,看来的确IDE为我们做了很多工作,隐藏了一些技术细节,有时候隐藏这些细节虽然可以方便我们,

12、却让我们离真相越来越远。最近使用Linux进行相关的编程操作,感悟还是挺多的。Windows下的层层封装的确让我们感到很方便,但同时也让我们编程变得越来越不灵活。因为我们不用再去了解底层的东西因此一遇到问题就会束手无策。这段时间一直用Linux进行编程,感觉很方便,跟我以前想象地完全不一样,而且我掌握了不少命令,比我以前用鼠标操作的时候快多了,而且在Bash下可以用Ctrl+Z随时中止正在运行的进程或命令,再用fg %id 重新运行。Linux下的编程也很方便,我还了解了Makefile的编写方法,在多文件编程的时候可以极高地提高效率。 总之,我之后会加强专业英语的学习,以便更好的利用Linu

13、x操作系统进行编程之路的学习。附录:实验代码#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>#define N 30 / 生产者的数目#define M 30 /消费者的数目#define p 20 / 缓冲数目int in = 0; / 生产者放置产品的位置int out = 0; / 消费者取产品的位置int buffp = 0; / 缓冲初始化为0, 开始时没有产品sem_t emp

14、ty_sem; / 同步信号量, 当满了时阻止生产者放产品sem_t full_sem; / 同步信号量, 当没产品时阻止消费者消费pthread_mutex_t mutex; / 互斥信号量, 一次只有一个线程访问缓冲int product_id = 0; /生产者idint prochase_id = 0; /消费者id/* 打印缓冲情况 */void print()int i;for(i = 0; i < p; i+) printf("%d ", buffi);printf("n");/* 生产者方法 */void *product()int

15、 id = +product_id;while(1) / 用sleep的数量可以调节生产和消费的速度,便于观察 sleep(1); /sleep(1); sem_wait(&empty_sem); pthread_mutex_lock(&mutex); in = in % p; printf("product%d in %d. like: t", id, in); buffin = 1; print(); +in; pthread_mutex_unlock(&mutex); sem_post(&full_sem); /* 消费者方法 */vo

16、id *prochase()int id = +prochase_id;while(1) / 用sleep的数量可以调节生产和消费的速度,便于观察 sleep(1);/sleep(1); sem_wait(&full_sem); pthread_mutex_lock(&mutex); out = out % p; printf("prochase%d in %d. like: t", id, out); buffout = 0; print(); +out; pthread_mutex_unlock(&mutex); sem_post(&em

17、pty_sem);int main()pthread_t id1N;pthread_t id2M;int i;int retN,RETM;/ 初始化同步信号量int ini1 = sem_init(&empty_sem, 0, M);int ini2 = sem_init(&full_sem, 0, 0); if(ini1 && ini2 != 0) printf("sem init failed n"); exit(1);/初始化互斥信号量int ini3 = pthread_mutex_init(&mutex, NULL);if(ini3 != 0) printf("mutex init failed n"); exit(1);/ 创建N个生产者线程for(i = 0; i < N; i+) reti = pthread_create(&id1i, NULL, product, (void *)(&i); if(reti != 0) printf("product%d creation failed n", i); exit(1);

温馨提示

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

评论

0/150

提交评论