多道程序缓冲区协调操作_第1页
多道程序缓冲区协调操作_第2页
多道程序缓冲区协调操作_第3页
多道程序缓冲区协调操作_第4页
多道程序缓冲区协调操作_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

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

文档简介

1、操作系统课程设计 报告多道程序缓冲区协调操作班级 学号姓名成绩指导教师2013年7月7日多道程序缓冲区协调操作一概述1.目的:(1)了解提出信号量的背景 (2)掌握信号量的基本概念及 PV 操作的原理 (3)进一步熟悉信号量解决的经典问题 (4)利用信号量的原理实现不同操作系统下同步互斥问题2.主要完成的任务:有10个Put操作要不断循环地向InBuffer送数据,有一个Move操作要不断地将InBuffer的数据取到OutBuffer,有20个GET操作要不断地从OutBuff中取数据。InBuffer的容量是10, OutBuff的容量是20, Put、 Move、 Get每次操作一个数据

2、,为了在操作的过程中要保证数据不丢失,每个Buffer每次只能接受一个Put或一个Move或一个Get,多个操作不能同时操作同一Buffer(即需要互斥操作)。设计一个多道程序完成上述操作。试用、原语(或Wait、Signal)协调Put、 Move、Get的操作,并说明每个信号量的含义、初值和值的范围。3.使用的开发工具:VMware Workstation, ubantu Linux4.解决的主要问题:需求分析 利用信号量实现缓冲区管理临界区协调问题。解决由于进程线程共享内存而出 现的与时间有关的错误。二使用的基本概念和原理信号量:为解决多进程线程同步与互斥问题,让两个或多个多道进程线程通

3、过特殊的变量展开交互。 线程:是进程的一个实体,是进程上下文中执行的代码序列,是被系统调度的基本单元。 进程:进程是正在运行的程序实体,并且包括这个运行的程序中占据的所有系统资源。 互斥与同步:进程的同步与互斥是指进程在推进时的相互制约关系。 进程同步:它主要源于进程合作,是进程间共同完成一项任务时直接发 生相互作用的关系。 进程互斥:它主要源于资源共享,是进程之间的间接制约关系。三总体设计生产者消费者问题是相互合作的进程关系的一种抽象,可以利用信号量机制来解决生产者消费者问题,利用互斥信号量mutex实现进程对缓冲池的互斥使用。对信号量的操作只能通过两个原子操作:Wait(s)和Signal

4、(s).Wait(s)是等待信号的操作,进行S=S-1操作;Signal(s)是发送信号的操作,进行S=S+1操作。wait 若s-1后仍大于或等于零,则进程继续执行;若s-1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度;若相加结果大于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度如下图所示,有10个PUT(相当于生产者)操作要不断循环地向Buffer1送数据,有一个Move(相当于搬运者)操作要不断地将Buffer1的数据取到Buffer2,有20个GET(相当于消费者)操作要不断地从Buff2中取数据。BUFF1是10,BUFF

5、2的容量是20, PUT、 MOVE、 GET每次操作一个数据,为了在操作的过程中要保证数据不丢失,每个Buffer每次只能接受一个PUT或一个Move或一个Get,多个操作不能同时操作同一BUFFER。设计一个多道程序完成上述操作。试用、原语协调PUT、 MOVE、GET的操作,并说明每个信号量的含义、初值和值的范围。设计总体流程图如下:四详细设计4.1线程规划我们创建三类线程:(1)PUT线程(往BUFFER1里放数据,相当于生产者)。(2)MOVE线程(从BUFFER1里取数据并放到BUFFER2里,相当于搬运者)。(3)GET线程(从BUFFER2里取数据,相当于消费者)。每类线程可由

6、用户自行设定线程的个数。4.2信号量的设置需要设置六个信号量full1 empty1 buff1 full2 empty2 buff2。各信号量含义及初值如下:full1表示buffer1是否有数据,初值为0;empty1表示buffer1是否有空间,初值为m;buff1表示buffer1是否可操作,初值为1;full2表示buffer2是否有数据,初值为0;empty2表示buffer2是否有空间,初值为n;buff2表示buffer2是否可操作,初值为1。4.3 函数 move 函数:创建move线程,使用p.v原语判断inbuffer是否有数据,若有数据,则从inbuffer接受数据;

7、sem_wait(&iFull);sem_wait(&sem1);sleep(1);data2=inBufferiOut;若无数据,则move程序阻塞。从inbuffer接收到数据之后,若outbuffer有空间则将接收到的数据输入到outbuffer。 sem_wait(&oEmpty);sem_wait(&sem2);sleep(1);outBufferoIn=data2;Put函数:分配空间给buffer1。wait(s) 若s-1后仍大于或等于零,则进程继续执行;若s-1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度;若相加结果大于

8、或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。Out函数:分配空间给buffer2。使用p.v判断move是否有数据,若有,则通过move接受数据并输出。若没有,则将out程序阻塞。五编码设计 1.程序源代码如下#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <errno.h>#include <sys/ipc.h>#include <semaphore.h

9、>/* 定义头变量 */sem_t iFull,iEmpty;sem_t oFull,oEmpty;int iIn=0,iOut=0,oIn=0,oOut=0;sem_t sem1,sem2;char inBuffer10;char outBuffer20;int data1,data2,data3;void put(void *arg);void move(void *arg);void get(void *arg);main(int argc, char *argv)int i,j;int *task110;int *task220;pthread_t id110,id2,id320

10、;int ret;/*初始化信号量imutex为1*/ret=sem_init(&sem1,0,1);if(ret!=0)perror("sem_init");/*初始化信号量omutex为1*/ ret=sem_init(&sem2,0,1);if(ret!=0)perror("sem_init");/*初始化信号量iFull为1*/ret=sem_init(&iFull,0,0);if(ret!=0)perror("sem_init");/*初始化信号量iEmpty为10*/ret=sem_init(&am

11、p;iEmpty,0,10);if(ret!=0)perror("sem_init");/*初始化信号量oFull为0*/ret=sem_init(&oFull,0,0);if(ret!=0)perror("sem_init");/*初始化信号量oEmpty为20*/ret=sem_init(&oEmpty,0,20);if(ret!=0)perror("sem_init");/*创建三个线程*/put线程for(i=0;i<10;i+)task1i = (int *)malloc(sizeof(int);*ta

12、sk1i = i;ret=pthread_create(&id1i,NULL,(void *)put,(void *)task1i);if(ret!=0)perror("pthread thread put error.");/move线程ret=pthread_create(&id2,NULL,(void *)move, NULL);if(ret!=0) perror("pthread thread move error.");/get线程for(j=0;j<20;j+)task2j = (int *)malloc(sizeof(

13、int);*task2j = j;ret=pthread_create(&id3j,NULL,(void *)get,(void *)task2j);if(ret!=0) perror("pthread thread get error.");for(i=0;i<10;i+)pthread_join(id1i,NULL);pthread_join(id2,NULL);for(j=0;j<20;j+)pthread_join(id3j,NULL);exit(0);/* put操作线程函数 */void put(void *arg)int i;int *th

14、readid1;threadid1 = (int *)arg;srand(time(NULL);while(1)sleep(1);data1= rand() % 128;/*信号量减一,P操作*/sem_wait(&iEmpty); sem_wait(&sem1);sleep(1);printf("put%d:iIn=%d,nThe data put into the inBuffer is:%dn",*threadid1,iIn,data1);inBufferiIn=data1;iIn=(iIn+1)%10;/*信号量加一,V操作*/ sem_post(&

15、amp;sem1);sem_post(&iFull); sleep(2);/* move操作线程函数 */void move(void *arg)int ret;while(1)/* move操作将数据取出inBuffer缓冲区 */sem_wait(&iFull);sem_wait(&sem1);sleep(1);data2=inBufferiOut;printf("move:iOut=%d,nThe data get out of the inBuffer is:%dn",iOut,data2);iOut=(iOut+1)%10; sem_pos

16、t(&sem1);sem_post(&iEmpty);sleep(1);/* move操作将数据放入outBuffer缓冲区 */sem_wait(&oEmpty);sem_wait(&sem2);sleep(1);outBufferoIn=data2;printf("move:oIn=%d,nThe data put into the outBuffer is:%dn",oIn,data2);oIn=(oIn+1)%20;sem_post(&sem2);sem_post(&oFull);sleep(1);/* get操作线程

17、函数 */void get(void *arg)int ret;int *threadid2;threadid2 = (int *)arg;while(1)sem_wait(&oFull);sem_wait(&sem2);sleep(1);data3=outBufferoOut;printf("get%d:oOut=%d,nThe data get out of the outBuffer is:%dn",*threadid2,oOut,data3);oOut=(oOut+1)%20;sem_post(&sem2);sem_post(&oEm

18、pty);sleep(1);六测试时出现过的问题及解决方法1. 一开始写程序时无从下手,后来经过老师指点将本程序的P.V原语写出,程序就可以按照P.V原语的顺序往下写。2. 一开始不明白程序的线程操作上锁与解锁的含义,后来经老师指导得知线程互斥与同步就是信号量的互斥与同步,创建信号量就可以表示出线程间的关系。3. 出现段错误,后改成输入的数据有随机数生成函数产生即解决此问题。 一开始不明白程序的线程操作上锁与解锁的含义,后来经老师指导得知线程互斥与同步就是信号量的互斥与同步,创建信号量就可以表示出线程间的关系。4. 编译时为出错,但在执行时出现段错误,后改成输入的数据有随机数生成函数产生即解决此问题。 七实验结果实验结果如下:八总结本软件利用ubantu Linux-VMware实现多线程的同步,用户可以直接观察多线程的运行,协调,并且可以设置线程的个数,缓冲区的容量,以及线程的速度。整个程序的设计过程中出现了很多问题,比如在设计过程中该设计几个类,各个类该完成什么样的功能,如何实现各个功能,一个类如何调用另一

温馨提示

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

评论

0/150

提交评论