计算机操作系统(第二版)课件:进程通信_第1页
计算机操作系统(第二版)课件:进程通信_第2页
计算机操作系统(第二版)课件:进程通信_第3页
计算机操作系统(第二版)课件:进程通信_第4页
计算机操作系统(第二版)课件:进程通信_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

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

文档简介

进程通信1.进程通信类型共享存储器系统通信管道通信消息传递系统通信客户-服务器系统通信2.消息缓冲队列通信机制3.Linux进程通信相关系统调用3.6进程通信3.6.1进程通信类型1.分析说明共享存储器系统通信的基本概念及性能特点2.说明消息传递系统通信基本概念(1)直接通信概念及类型(2)间接通信概念3.说明管道通信概念(1)无名管道概念(2)有名管道概念4.客户/服务器系统通信(自学)(1)socket概念及通信流程(2)远程过程调用概念及流程3.6进程通信3.6.1进程通信类型1.共享存储器系统通信通过共享存储分区实现进程之间的信息交换通信过程:

(1)申请共享存储分区;(2)将共享存储分区映射到本进程地址空间中;(3)进行数据读写;(4)解除共享存储分区映射;(5)删除共享存储分区:内核共享存储区共享存储分区进程1地址空间共享内存映射区进程2地址空间共享内存映射区共享存储器系统通信方式的特点:

(1)最大的特点是没有中间环节,通信直接快速(2)该通信机制没有提供进程同步机制。举例:#include<stdio.h>#include<sys/types.h>#include<sys/msg.h>#include<sys/ipc.h>#include<unistd.h>#defineSHMKEY75intshmid,i;int*addr;voidCLIENT()发送进程{inti;shmid=shmget(SHMKEY,1024,0777);addr=shmat(shmid,0,0);for(i=9;i>=0;i--){ while(*addr!=-1);//是否已读取 printf("(client)sent"); *addr=i; printf("%d\n",*addr); sleep(1);}}voidSERVER()接收进程{shmid=shmget(SHMKEY,1024,0777|IPC_CREAT);addr=shmat(shmid,0,0);//附接到用户的虚地址空间do{ *addr=-1; while(*addr==-1);//client是否已经写入 printf("(server)received%d\n",*addr); sleep(1);}while(*addr);

shmctl(shmid,IPC_RMID,0);}main(){intp1,p2;p1=fork();if(p1==0) SERVER();else{p2=fork(); if(p2==0)CLIENT();}wait(0);wait(0);}进程间的数据交换是以消息(或报文)为单位。在消息通信中,接收方和发送方之间有明确的协议和消息格式。

消息格式:消息头消息正文消息头:存放消息传输时所需的控制信息。3.6进程通信3.6.1进程通信类型2.消息传递系统通信你会在消息头中设置哪些内容?2.消息传递系统通信

消息传递系统实现类型:3.6.1进程通信类型

直接通信:send(),receive()

直接通信同步关系阻塞发送,阻塞接收无阻塞发送,无阻塞接收无阻塞发送,阻塞接收2.消息传递系统通信

消息传递系统实现类型

间接通信:

通信双方利用一个共享的称为信箱的中间实体实现信息交换。发送进程A信箱头

…信箱体接收进程Bsend(m)receive(m)邮箱通信结构信箱头:信箱名、信箱大小、创建者、存取信件指针、信件数量等信箱体:存放消息信箱信箱创建者私用信箱:用户进程公用信箱:操作系统共享信箱:用户进程

管道通信概念:管道:用于连接一个发送进程和一个接收进程,以实现它们之间通信的共享文件(pipe文件,又称为FIFO文件)FIFO文件的写入和读出:严格遵循先进先出,不支持文件定位操作。进程2读出进程1写入3.6进程通信3.6.1进程通信类型3.管道(pipe)通信fd[1]fd[0](1)无名管道:intpipe(intfd[2])

fd[1]为写入端,fd[0]为读出端。用于父子或兄弟进程间通信(2)有名管道:

intmkfifo(constchar*pathname,mode_tmode)用于任意进程间通信(又称FIFO通信)

两种实现机制:写端读端fd[1]fd[0]write(fd[1],buf,size)read(fd[0],buf,size)pipe(fd)3.6进程通信3.6.1进程通信类型3.管道(pipe)通信

管道通信应注意的问题:写端读端fd[1]fd[0]write(fd[1],buf,size)read(fd[0],buf,size)pipe(fd)

对管道的读写操作必须互斥进行

对管道的读写操作必须同步进行通信双方必须同时存在:有名管道管道常用于单向通信3.6进程通信3.6.1进程通信类型3.管道(pipe)通信编写一程序,建立一个管道。同时,父进程生成了进程P1和P2,这两个子进程分别向管道中写入各自的字符串,父进程读出它们。fd[1]fd[0]pipe(fd)子进程P1父进程子进程P2

无名管道应用举例:3.6进程通信3.6.1进程通信类型3.管道(pipe)通信#include<stdio.h>#include<unistd.h>main(){

inti,r,p1,p2,fd[2];

charbuf[50],s[50];

pipe(fd); p1=fork();

if(p1==0)

{

lockf(fd[1],1,0);

sprintf(buf,“childprocess1issending\n”);

printf("childprocess1!\n");

write(fd[1],buf,50);

sleep(5);

lockf(fd[1],0,0);

exit(0);

}lockf:用于锁定文件的某些段或整个文件头文件:#include<unistd.h>参数定义:intlockf(files,function,size) intfiles,function:longsizefunction:1锁定,0解锁Size:0,表示从文件的当前位置到文件尾

无名管道应用举例:3.管道(pipe)通信

else

{

p2=fork();

if(p2==0)

{

lockf(fd[1],1,0);

sprintf(buf,"childprocess2issending!\n");

printf("childprocess2!\n");

write(fd[1],buf,50);

sleep(5);

lockf(fd[1],0,0);

exit(0);

}

else

{

wait(0);

if((r=read(fd[0],s,50))==-1)

printf("can'treadpipe\n");

else

printf("%s\n",s);

wait(0);

if((r=read(fd[0],s,50))==-1)

printf("can'treadpipe\n");

else

printf("%s\n",s);

exit(0);

}}}/*

mainend*/

无名管道应用举例:客户端提出请求,服务器提供服务3.6进程通信3.6.1进程通信类型4.客户-服务器系统通信(C/S模式)套接字(Socket)Socket又称为套接字或插口,是一条通信线路两头端口的抽象表示。Socket网络地址连接类型网络规程有连接(TCP)无连接(UDP)通信流程客户端提出请求,服务器提供服务3.6进程通信3.6.1进程通信类型4.客户-服务器系统通信(C/S模式)远程过程调用(RPC)RPC允许客户机上的进程通过网络调用位于远程主机上的过程。按照系统规定的消息结构将调用过程的标识符及参数打包成消息3.6进程通信1.分析消息缓冲队列通信机制的基本思想2.说明消息缓冲队列通信机制的相关数据结构

消息缓冲区

消息缓冲队列3.分析发送原语实现过程4.分析接收原语实现过程3.6.2消息缓冲队列通信机制发送进程发送区设置公用缓冲区复制消息接收队列挂入取消息消息缓冲区复制接收进程接收区3.6进程通信3.6.2消息缓冲队列通信机制1.基本思想:消息缓冲区:

structmesg_buffer{intsender;char*text;intsize;timesend_time;structmesg_buffer*next;

……}buffer;2.相关数据结构:3.6进程通信3.6.2消息缓冲队列通信机制消息缓冲队列:空白消息缓冲区队列;接收进程的消息队列;PCB中与通信有关的数据项:

structmessage_buf*mq:消息队列队首指针;semaphoremutex:消息队列互斥信号量;semaphoresm:消息队列同步信号量

Freebuff_mutex;Freebuff_sm2.相关数据结构:哪些进程会使用这个队列?哪些进程会使用这个队列?3.6进程通信3.6.2消息缓冲队列通信机制3.发送原语:send()申请空白消息缓冲区;填写该空白消息缓冲区;将该消息缓冲区挂到接收进程的消息队列上。发送原语需要完成哪些工作呢?3.6.2消息缓冲队列通信机制要成功申请到一个空白消息缓冲区,需要满足几个条件?3.发送原语:send()proceduresend(receiver,a)

{ getbuf(a.size,i); copy(i,a);receiver_pcb=getpcb(receiver);wait(receiver_pcb.mutex);insert(receiver_pcb.mq,i);signal(receiver_pcb.mutex);signal(receiver_pcb.sm)}

wait(freebuf_sm);wait(freebuf_mutex);getafreebufsignal(freebuf_mutex);3.6.2消息缓冲队列通信机制从接收队列中取下一个消息缓冲区;将该消息缓冲区内容复制到接收区中;将该消息缓冲区清空后挂到空白消息缓冲队列上。4.接收原语:receive()接收原语需要完成哪些工作呢?要成功取得一个消息缓冲区,需要满足几个条件?3.6.2消息缓冲队列通信机制procedurereceive(b)

{

wait(receiver_pcb.sm) wait(receiver_pcb.mutex); remove(receiver_pcb.mq,j) signal(receiver_pcb.mutex); copy(b,j); releasebuf(j);

}wait(freebuf_mutex);putafreebufsignal(freebuf_mutex);signal(freebuf_sm);4.接收原语:receive()3.6.2消息缓冲队列通信机制3.1进程通信1.共享存储器系统通信的基本概念及性能特点2.消息传递系统通信基本概念:直接通信、间接通信3.管道通信概念:无名管道、有名管道4.消息缓冲队列通信机制的基本思想:(1)发送原语实现过程(2)接收原语实现过程本节知识小结哪个小组来总结下?3.6进程通信省平台课堂在线测试(6分钟)3.6进程通信3.6.3Linux/openEuler进程通信系统调用管道通信机制IPC消息队列通信机制共享内存通信无名管道:1.Linux/openEuler管道通信机制

无名管道只能用于具有亲缘关系的进程之间的通信。

无名管道是半双工的

无名管道没有对应的磁盘映像,只存在于内存中基本概念:创建无名管道:pipe()intpipe(intfiledes[2])功能:在内存缓冲区中创建一个管道,主要是建立相关VFS对象,并将读写该管道的一对文件描述符保存在filedes[2]中。3.6.3Linux/openEuler进程通信系统调用

从管道中读取数据:pipe_read()

阻塞型读取数据:管道大小为p,请求读取n管道大小至少有一个写进程没有写进程有睡眠写进程无睡眠写进程p=0读取n个字节并返回n,当管道缓冲区为空时等待写进程写数据等待写进程写数据,然后再读取数据返回00<p<n读取P个字节并返回P;管道缓冲区中还剩0个字节p≥n读取n个字节,返回n,管道缓冲区中还剩p-n个字节

非阻塞型读取数据:管道大小为p,请求读取nP<n:读取p字节并返回p;P≥n:读取n字节并返回n1.Linux/openEuler管道通信机制无名管道:无名管道:向管道中写入数据:pipe_write()缓冲区剩余空间至少有一个读进程没有读进程阻塞写非阻塞写写入失败,内核向写进程发送SIGPIPE信号,并返回-EPIPEu<n≤4096等待,直到有n-u个字节被读出为止,写入n个字节并返回n返回-EAGAIN,提醒以后再写n>4096写入n个字节(必要时要等待)并返回n如果u>0,写入u字节并返回u;否则就返回-EAGAINu≥n写入n个字节并返回n管道中空闲空间u字节,请求写入n字节1.Linux/openEuler管道通信机制有名管道创建有名管道:可用于任意进程间的信息交换intmkfifo(constchar*pathname,mode_tmode)功能:在磁盘上创建一个有名管道文件打开有名管道:intopen(constchar*pathname,intflags)从有名管道中读取数据:管道大小阻塞读非阻塞读p=0读进程阻塞,等待写进程写入数据返回-1,当前errno值为EAGAIN,提醒以后再试0<p<n读取p个字节并返回pp≥n读取n个字节并返回n1.Linux/openEuler管道通信机制有名管道向有名管道中写入数据:缓冲区剩余空间阻塞写非阻塞写u<n≤4096等待,直到有n-u个字节被读出为止,写入n个字节并返回n返回-EAGAIN,提醒以后再写n>4096

写入n个字节(必要时要等待)

并返回n如果u>0,写入u字节并返回u;否则就返回-EAGAINu≥n写入n个字节并返回n1.Linux/openEuler管道通信机制相关数据结构2.Linux/openEuler的IPC消息队列通信机制

消息缓冲区structmsgbuf:消息缓冲区设计举例:structmsgbuf{ /*消息定义的参照格式*/longmtype;/*消息类型(大于0的长整数)*/charmtext[1]; /*消息正文*/};structmy_msgbuf{longmtype;/*Messagetype*/longsender_id,receiver_id;charmytext[1024];/*text*/};相关数据结构

消息头结构:msg_msg和msg_msgseg结构structmsg_msg{structlist_headm_list;/*指向消息队列中的下一条消息*/longm_type;/*消息类型,同structmsgbuf中的mtype*/intm_ts;/*消息正文的大小*/structmsg_msgseg*next;/*消息的下一部分*/void*security;};/*该结构后面紧接着存放消息正文*/structmsg_msgseg{structmsg_msgseg*next;};msg_msgText4072Bnext2.Linux/openEuler的IPC消息队列通信机制相关数据结构:msg_msgText4072Bnextmsg_msgsegTextnextmsg_msgsegTextnext同一个消息放在3个消息缓冲区中

消息头结构:msg_msg和msg_msgseg结构2.Linux/openEuler的IPC消息队列通信机制相关数据结构:

消息队列结构:msg_queuestructmsg_queue{ structkern_ipc_permq_perm;/*消息队列的kern_ipc_perm*/ time_tq_stime; /*最近一次调用msgsnd()的时间*/ time_tq_rtime; /*最近一次调用msgrcv()的时间*/ time_tq_ctime; /*最近一次修改时间*/ unsignedlongq_cbytes; /*队列中的总字节数*/ unsignedlongq_qnum; /*队列中的消息个数*/ unsignedlongq_qbytes; /*队列中最大消息的字节数*/ pid_tq_lspid; /*最近一次调用msgsnd()的PID*/ pid_tq_lrpid; /*最近一次调用msgrcv()的PID*/ structlist_headq_messages;/*队列中的消息链表*/ structlist_headq_receivers;/*接收消息的进程链表*/ structlist_headq_senders;/*发送消息的进程链表*/};IPC消息队列数最多为16个,每个消息大小最大为8192B,一个消息队列中全部消息大小最大为16384B2.Linux/openEuler的IPC消息队列通信机制相关系统调用intmsgget(key_tkey,intmsgflg)功能:新创建一个消息队列并返回其标识符,或者返回具有相同键值的已存在的消息队列的标识符intmsgsnd(intmsqid,structmsgbuf*msgp,size_tmsgsz,intmsgflg)功能:向标识符为msqid的消息队列中发送一个消息ssize_tmsgrcv(intmsqid,structmsgbuf*msgp,size_tmsgsz,longmsgtyp,intms

温馨提示

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

评论

0/150

提交评论