好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

操作系统实验 进程通信.doc

9页
  • 卖家[上传人]:飞***
  • 文档编号:43686748
  • 上传时间:2018-06-07
  • 文档格式:DOC
  • 文档大小:521KB
  • / 9 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 进程通信(实验二)【实验目的】:掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮 箱理解进程通信中的同步问题以及解决该问题的方法实验原理】:邮箱机制类似于日常使用的信箱对于用户而言使用起来比较 方便,用户只需使用 send()向对方邮箱发邮件 receive()从 自己邮箱取邮件, send()和 receive()的内部操作用户无需 关心因为邮箱在内存中实现,其空间有大小限制其实 send()和 receive()的内部实现主要还是要解决生产者与消费 者问题进程 A进程 B信箱 A信箱 BSend()Send()receive()receive()【实验内容】:进程通信的邮箱方式由操作系统提供形如 send()和 receive()的系统调用来支持,本实验要求学生首先查找资料了 解所选用操作系统平台上用于进程通信的系统调用具体形式,然 后使用该系统调用编写程序进行进程间的通信,要求程序运行结 果可以直观地体现在界面上在此基础上查找所选用操作系统平 台上支持信号量机制的系统调用具体形式,运用生产者与消费者 模型设计实现一个简单的信箱,该信箱需要有创建、发信、收信、 撤销等函数,至少能够支持两个进程互相交换信息,比较自己实 现的信箱与操作系统本身提供的信箱,分析两者之间存在的异同。

      实验背景介绍实验背景介绍进程间通信有如下目的:数据的传输,共享数据,通知事情,资源共享, 进程控制进程间的通信机制(IPC) ,就是多进程相互通信,交换信息的方法 Linux IPC 机制包括,信号和管道是其中的两个,还支持传统的 UNIX SYSTM- V 的 IPC 机制 信号主要用来通知进程异步事情的发生,最初信号设计的目的是为了处理错误, 他们也用来作为最基本的 IPC 机制 管道是单向的,先进先出,先入先出,无结构的,固定大小的数据流 UNIX System V 机制中的三种进程间通信机制,它们是: 消息队列:用于进程之间传递分类的格式化数据 信号量:用于通信之间的同步控制信号量通常与共享存储器方式一起使用 共享内存:使不同进程通过共享彼此的虚拟空间而达到相互对共享区操作和数 据通信它们之间有一个共同的特点,就是它们使用相同的认证方法,一个进 程只有通过系统调用想内核传递一个唯一的引用标识符才能访问这些资源实验环境实验环境: ubuntu linux 操作系统实验原理分析:实验原理分析:进程 A 和 进程 B 共享内存 C 和 D,并通过用 P,V 原理来控制它们对共 享内存的读写。

      共享内存进程ACD进程BsendrecieveSendrecieve通过 PV 控制读写信号量 S0,S1,S2,S3 其中 S0,S1 控制 C,S2,S3 控制 D 其中 S0 表示内存中有几个信息,S1 表示内存还可以存几 个信息同理可得 S2,S3.PV 简略图:简略图:进程 A: 发送信息 ...... P(S1)Send ()V(S0) …… 接受消息 …… P(S2) Receive() V(S3) ……..进程 B: 发送信息 ...... P(S3)Send ()V(S2) …… 接受消息 …… P(S0) Receive() V(S1) ……..函数调用分析函数调用分析:共享内存的创建,读,写,删除相当于信箱的创建,收信,发信,撤销等共享内存区域是被多个进程共享的一部分物理内存,进程可以 把这些区域映射到它们地址空间的任一适合的虚拟地址范围这些地址范围对 每一个进程来说都是不同的,映射后这些区域就可以像任何其他内存位置那样 被访问,而不需要对它们使用读写调用进程向共享内存中写入数据,那么这 个区域的所有进程可以立即看见共享区的新内容shmget(key_t key, size_t size, int shmflg);key 标识共享内存的键值 : 0/IPC_PRIVATE。

      当 key 的取值为 IPC_PRIVATE,则函数 shmget()将创建一块新的共享内存;如果 key 的取值 为 0,而参数 shmflg 中设置了 IPC_PRIVATE 这个标志,则同样将创建一块 新的共享内存 size 是要建立共享内存的长度 shmflg 主要和一些标志有关其中有效的包括 IPC_CREAT 和 IPC_EXCL,它们的功能与 open()的 O_CREAT 和 O_EXCL 相当 IPC_CREAT 如果共享内存不存在,则创建一个共享内存,否则打开操作 IPC_EXCL 只有在共享内存不存在的时候,新的共享内存才建立,否则就产 生错误 成功返回共享内存的标识符;不成功返回 -1,errno 储存错误原因例如: shmid=shmget(SHMKEY,256,IPC_CREAT|0600); 创建了一个 key=SHMKEY,大小为 256 的共享内存并把值给了 shmid.s sh hm ma at t( ( i in nt t s sh hm mi id d , , c ch ha ar r * *s sh hm ma ad dd dr r , , i in nt t s sh hm mf fl la ag g ) ); ;shmat()是用来允许本进程访问一块共享内存的函数。

      int shmid 是那块共享内存的 ID char *shmaddr 是共享内存的起始地址 int shmflag 是本进程对该内存的操作模式如果是 SHM_RDONLY 的话, 就是只读模式其它的是读写模式 成功时,这个函数返回共享内存的起始地址失败时返回 -1例如:addr=(char *) shmat(shmid,NULL,0); 内存地址映射把 id 为 shmid 共享内存的首地址给了 addr,因此我们可以通过 addr 来访问共享内存,相当于,我们知道了数组的首地址,然后在对数组进行 操作一样shmdt((Shared Memory Detach))函数与该共享内存块脱离将由 shmat 函数返回的地址传递给这个函 数成功共时返回 0,不成功返回 1,注意共享内存并未删除它,只是使该共享 进程当前,进程不再可用如果当释放这个内存块的进程是最后一个使用该内 存块的进程,则这个内存块将被删除例如: shmdt(addr); 我们有了共享内存的首地址之后,对共享内存的读写就相当于对一个数组的 读写 写: strcpy(addr,“linux“); 就把 linux 字符放进了共享内存。

      读: printf(“%s\n”,addr); 综上所得,我们就很容易理解共享内存的一些操作; 例: pid=shmget(Key,buffersize,IPC_CREAT|0600);//创建共享内存char *addr;addr=(char *)shmat(pid,NULL,0);//映射首地址strcpy(addr,“ This is the message which the parent have sent!“);//写共享内 存shmdt(addr);//释放共享内存 信号量:信号量:是为了控制进程对资源的使用而发明的信号量是具有整数值的对象, 它的工作原理如下;它支持两种原子操作 P 和 V,P 操作减少信号量的值,如果 某一个信号量的值小于 0,则操作阻塞,V 操作增加信号量的值,如果结果值 大于或等于 0,V 操作就要唤醒一个等待进程想要获得资源时使用 P 操作, 每次请求成功,它都要减少信号量的值,信号量的值减至 0 时,下一个 P 操作 将被阻塞,释放资源的时候使用 V 操作,它增加信号量的值,同时唤醒被阻塞 的进程semget( semkey, count, flag);其中 semkey 和 flag 类似于建立消息和共享存储区域, semkey 是用户指定 的关键字,count 是指定信号量数组的长度。

      Semid=(senkey ,4,0777|IPC_CREAT);创建了一个关键字为 semkey 的含有 4 个 元素的信号量数组 注意信号量数组序号是从 0 才是编址`s se em mo op p( (s se em mi id d, , s st tr ru uc ct t s se em mb bu uf f s se em mo op pa ar rr ra ay y[ [] ], , s si iz ze e_ _t t n no op ps s ) ); ; 函数中参数 semid 是一个通过 semget 函数返回的一个信号量标识符,参 数 nops 标明了参数 semoparray 所指向数组中的元素个数参数 semoparray 是一个 struct sembuf 结构类型的数组指针,结构 sembuf 来说 明所要执行的操作,其定义如下: struct sembuf{ unsigned short sem_num; //信号量集中的某一个 信号量short sem_op; // sem_op 指明所要执行的操作 (1 表示 V 操作,-1 表示P 操作)short sem_flg; } 例:I In nt t P P( (i in nt t s se em mi id d) ){ struct sembuf p;P.sem_num=1;/对第二个信号量;P.sem_op=-1;//p 操作;P.sem_flag=SEM_UNDO;semop(semid, }I In nt t V V((i in nt t s se em mi id d)){ struct sembuf p;P.sem_num=2;//对第三个信号量;P.sem_op=1;//V 操作;P.sem_flag=SEM_UNDO;semop(semid, }对信号量进行控制s se em mc ct tl l( (i in nt t s se em mi id d, ,i in nt t n nu um m, ,i in nt t c cm md d, ,u un ni io on n a ar rg g) ); ; 系统调用 semctl()的 semid 参数是关键字值。

      第二个参数是信号量数目参数 cmd 中可以使用的命令中 SETVAL 设置信号量集中的一个单独的 信号量的值返回值:如果成功,则为一个正数如果失败,则为 -1 union semun {int val;struct semid_ds *buf;unsigned short *array; } sem; sem.val=0;//设置初值为 0; semctl(sem_id,0,SETVAL,sem);//对第一个信号量设置初值为 0; 综上所得涉及到我们需要了全部调用函数,只要将这些函数合理的组合 在一起,就得到了我们想要的实验效果了实实验验调调试试过过程程::创建共享内存和信号量以及初始状态A 发送信息到共享内存 C,相当于 A 给 B 发送邮件 B 从共享内存 C 中读取信息,相当于接受了邮件并查看了 同理可得实验扩展:由实验的 PV 控制可知,当进程 A 的发送信息被挂起时,下面的进程 B 收信息也被挂起时不符合常理,若调用了 fork()函数,进程 A 又分为父进程和子进程与题意不符故可引进线程,线程1 为收信息,线程 2 为发信息调用函数:i in nt t p pt th hr re ea ad d_ _c cr re ea at t( (p pt th hr re ea ad d_ _t t * *t th hr re ea ad d, , p pt th hr re ea ad d_ _a at tt tr r_ _t t * *a at tt tr r, ,v vo oi id d * *( (* *s st ta ar rt t_ _r ro 。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.