资源预览内容
第1页 / 共51页
第2页 / 共51页
第3页 / 共51页
第4页 / 共51页
第5页 / 共51页
第6页 / 共51页
第7页 / 共51页
第8页 / 共51页
第9页 / 共51页
第10页 / 共51页
亲,该文档总共51页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
4.6 进程通信进程通信n进程通信是指进程之间的信息交换。n进程互斥与同步交换的信息量较少且效率较低,因此称这两种进程通信方式为低级进程通信方式,相应地也将P、V原语称为两条低级进程通信原语。n高级进程通信方式是指进程之间以较高的效率传送大量数据。进程通信的类型进程通信的类型n高级进程通信方式可分为三大类:n共享存储器系统n消息传递系统n管道通信系统或共享文件系统共享存储器系统共享存储器系统n相互通信的进程共享某些数据结构或共享存储区。n基于共享数据结构的通信方式:诸进程通过公用某些数据结构交换信息。如生产者-消费者问题。n基于共享存储区的通信方式:在存储器中划出一块共享存储区,诸进程可通过对共享存储区进行读或写来实现通信。包括建立共享存储区、附接及断接。消息传递系统消息传递系统n在消息传递系统中,进程间的数据交换以消息为单位,程序员直接利用系统提供的一组通信命令(原语)来实现通信。n消息传递系统因其实现方式不同可分为:n直接通信方式:发送进程将消息发送到接收进程,并将其挂在接收进程的消息队列上;接收进程从消息队列上取消息。n间接通信方式:发送进程将消息发送到信箱,接收进程从信箱中取消息。共享文件(管道)通信共享文件(管道)通信n共享文件(管道)通过连接读进程和写进程的共享文件来实现读写进程之间通信。4.6.1 消息缓冲通信消息缓冲通信n消息缓冲通信是直接通信方式的一种实现。系统通过两条通信原语Send及Receive进行通信。n为了实现消息通信,发送进程应先在自己的工作区中设置一个发送区,把欲发送的消息填入其中,然后再用发送原语将其发送出去。接收进程调用接收原语从自己的消息缓冲队列中摘下第一个消息,并将其内容复制到自己的消息接收区内。消息缓冲队列通信机制中的数据结构n消息缓冲区的数据结构如下: struct message sender; 发送者进程标识符 size; 消息长度 text; 消息正文 next; 指向下一个消息缓冲区的指针 在PCB中还应增加struct PCB mq;消息队列队首指针 mutex;消息队列互斥信号量 sm;消息队列资源信号量 发送原语描述void send(receiver,a)receiver为接收者标识号,a为发送区首址 向系统申请一个消息缓冲区i; 将发送区a中的消息复制到i中; 获得接收进程的内部标识j; P(mutex); 把消息插入j的消息队列上; V(mutex); V(sm); 接收原语描述void receive(b)b为接收区首址 获得接收进程内部标识j; P(sm); P(mutex); 将消息队列中的第一个消息移出; V(mutex); 将消息复制到接收区b; send(B,a); sender:A size:6 text:Hello!两个进程进行通信的过程进程APCB(B)进程B receive(b) sender:A size:6 text:Hello! mq mutex smsender:Asize:6text:Hello!next:0ab第一个消息缓冲区4.6.2 信箱通信信箱通信n信信箱箱通信方式中,进程之间通信需要通过共享数据结构实体-信箱来进行。n信箱是一种数据结构,其中存放信件。n信箱逻辑上分成信箱头和信箱体两部分。n信箱头中存放有关信箱的描述。n信箱体由若干格子组成,每格存放一个信件,格子的数目和大小在创建信箱时确定。 信箱通信原语n信箱通信原语包括:n信箱的创建和撤消:n消息的发送和接收:Send(mailbox,message);Receive(mailbox,message);4.6.3 共享文件n使用共享文件通信时,基本上采用文件系统的原有机制实现。包括创建、打开、关闭、读写等。n管道机制应提供以下三方面的协调能力:互斥:诸进程互斥读写管道同步:管道空、满情况处理存在:确定对方是否存在共享文件通信示意图1n初始时,其长度为4,系统将管道看成一个循环队列。按先进先出的方式读写。inout A B C Dn写入字符E后,管道长度为5inout A B C D E共享文件通信示意图2n读一个字符后,管道长度为4inout B C D En若管道容量为n且in=n时,再写入一个字符,则in移到管道的另一端。inout D E XUNIX的进程同步与通信P256nUNIX的早期版本中,为进程的同步与通信提供了:软中断信号管道机制n在UNIX SYSTEM 中,推出了新的进程通信机构IPC:消息机制共享存储区机制信号量机制软中断信号n软中断信号(简称信号)是一种实现进程间简单通信的设施,用于通知对方发生了异常事件。nUNIX SYSTEM 中,共有19个软中断信号。n软中断是对硬件中断的一种模拟,接收进程在收到软中断信号后,将按照事先的规定去执行一个软中断处理程序。n软中断处理程序必须等到接收进程执行时才能生效。信号的发送信号的发送n信号的发送是指由发送进程把信号发送到指定进程信号域的某一位上。n如果目标进程正在一个可被中断的优先级上睡眠,核心便将它唤醒,发送过程就此结束。n一个进程可能在其信号域中有多个位被置位,代表有多种类型的信号到达,但对于一类信号,进程却只能记住其中的一个。发送信号n系统调用kill向一个进程或一组进程发送一个信号。该系统调用的语法格式如下:int kill(pid,sig);int pid,sig;n其中,sig是要发送的信号,pid参数是进程标识号。 pid参数除了可以取进程标识号之外,还可以取下列一些特殊值:pid参数特殊值npid为0:表示把信号发送给与发送进程同组的所有进程,也包括发送进程自己。npid为 -1且发送进程的有效用户标识符不是超级用户:表示把信号发送给其实际用户标识符与发送进程的有效用户标识符相同的所有进程,也包括发送进程本身在内。npid为-1且发送进程的有效用户标识符为超级用户:表示把信号发送给除了一些特殊系统进程之外的所有进程。npid是一个非-1的负数:表示把信号发送给组号为pid绝对值的进程组中的所有进程。设置信号的处理方式设置信号的处理方式n系统调用signal用于设置信号的处理方式。其语法格式如下: void (* func)( ) signal(sig,func)n其中,func为收到软中断信号sig后进程希望调用函数的地址。n19类信号如表所示。 func的取值情况nfunc的取值可以分成三种情况:nfunc1时,进程对信号sig不予理睬。nfunc0时,即缺省处理,对大多数软中断信号的缺省处理是终止进程。nfunc为其他整数值时,它的值是指向信号处理程序的指针。 信号的处理n检查软中断信号的时机:n进入或退出低优先级睡眠状态n即将从核心态返回用户态n信号的处理方式:n忽略n缺省处理,即终止进程n执行用户设置的软中断处理程序管道n管道是指能连接某些读进程和写进程的、专门用于进程通信的共享文件。n管道允许读/写进程按先进先出的方式传送数据,即写进程从管道的一端向管道写入数据,读进程从管道的另一端读出数据。管道的类型管道的类型n管道的类型有:n无名管道n有名管道n有名管道和无名管道的读写方式是相同的。无名管道无名管道n无名管道是用系统调用pipe()建立的无名文件,用该系统调用所返回的文件描述符来标识该文件。n只有调用pipe的进程及其子孙进程才能利用该管道文件进行通信。有名管道有名管道n有名管道是利用mknod系统调用建立的,是可以在文件系统中长期存在的具有路径名的文件,n其他进程可以知道有名管道的存在并能利用路径名来访问该文件。n对有名管道的访问方式象访问其他文件一样,都需先用open系统调用去打开它。pipe文件的建立文件的建立npipe系统调用建立一个无名管道。其语法格式如下:n int pipe(fdes);n int fdes2;n核心创建一个管道时须完成下述工作:n分配磁盘和内存索引节点。n为读进程和写进程分配文件表项。n分配用户文件描述符。在读进程和写进程的用户文件描述符表中,分别分配一个表项,并将文件描述符fdes0和fdes1分别返回给读进程和写进程。Pipe涉及的数据结构读进程写进程用户文件描述符表文件表内存索引节点表外存fpfp文件指针文件指针索引节点PIPE文件pipe文件的大小限制文件的大小限制npipe文件只使用索引节点中的直接地址项。n核心将索引节点中的直接地址项作为一个循环队列来管理,为它设置一个读指针和一个写指针,按先进先出顺序进行读和写。进程写管道n进程向管道写数据时,可能有以下两种情况:n管道中有足够的空间存放要写的数据,此时每写一数据块后核心便自动增加地址项的大小。写操作完成后,核心修改索引节点中的写指针,并唤醒所有因该管道空而睡眠等待的读进程。n管道中无足够的空间存放要写入的数据,此时核心对该索引节点作标记后让写进程睡眠,等待数据从管道中排出。上述情况的一个例外是,当进程写的数据量大于管道的容量时,核心将尽可能多的数据写到管道中,然后使进程睡眠,直到获得更多的空间。进程读管道n当进程从管道读数据时,同样会有两种情况:n管道中有足够的数据供进程读。此时,进程便从读指针所指位置开始读数据,每读出一个数据块后,便增加地址项的大小。读操作结束后,核心修改索引节点中的读指针,并唤醒所有睡眠的写进程。n进程要读的数据比管道中的数据多。此时,读进程将返回管道中当前所有的数据。如果管道为空,进程一般将进入睡眠,直到一个写进程将数据写入管道,再将读进程唤醒。消息n消息是一个格式化的可变长的信息单元。消息机制允许进程向其他进程发送消息。当一个进程收到多个消息时,可将这些消息排成一个队列。n在UNIX中,消息机制向用户提供了四个系统调用,分别用于建立、发送、接收和管理消息。消息机制的数据结构消息机制的数据结构nUNIX的消息机制中使用了两种数据结构:n消息首部:消息首部中记录消息的类型、大小、指向消息数据区的指针、消息队列的链接指针等。n消息队列头标:每个消息队列的消息头标中,包含了指向消息队列中第一个消息的指针和指向最后一个消息的指针,队列中消息的数目,队列中消息数据的总字节数,队列所允许的消息数据的最大字节总数,还可以含有最近一次执行发送操作的进程标识号和时间等。消息和消息队列示意图 消息队列头标消息首部数据区消息队列的建立和描述符的获取消息队列的建立和描述符的获取n在UNIX系统中,系统调用msgget用来建立消息队列或者获取消息队列的描述符。该系统调用的语法格式如下:nint msgget(key,msgflg);nkey_t key;nint msgflg;n其中,key是用户指定的消息队列的名字;msgflg是用户设置的标志和访问方式。如IPC_CREAT表示系统中若无以key命名的消息队列,则建立消息队列;若该队列已存在,则返回该消息队列的描述符。消息的发送消息的发送n系统调用msgsnd( )向指定的消息队列发送一个消息,并将发送消息链接到该消息队列的尾部。系统调用的语法格式为:nint msgsnd(msgid,msgp,msgsz,msgflg);nint msgid,msgsz,msgflg;nstruct msgbuf *msgp;n其中,msgid是由msgget返回的消息队列描述符;msgp是指向用户消息缓冲区的指针。msgsz是消息的长度,msgflg规定了当无内存空间存储消息时,进程是等待还是立即返回。消息的接收消息的接收n系统调用msgrcv( ) 从指定消息队列中接收指定类型的消息,其语法格式如下:nint msgrcv (msgid, msgp, msgsz, msgtyp, msgflg);nint msgid,msgsz,msgflg;nstruct msgbuf * msgp;nlong msgtyp;n其 中 , msgid、 msgp、 msgsz、 msgflg与msgsnd中的对应参数相似,msgtyp是接收消息的类型。msgtyp的取值的取值nmsgtyp的取值有:nmsgtyp0时,核心寻找消息队列中的第一个消息,并将它返回给调用者;nmsgtyp为正整数时,核心返回给定消息类型的第一个消息;nmsgtyp为负整数时,核心应在其类型值小于或等于msgtyp绝对值的所有消息中,选出其类型值最低的一个消息返回。消息队列的操纵消息队列的操纵n用户在建立了消息队列后,可以利用msgctl系统调用来读取它的状态信息并进行修改,如查询消息队列描述符、修改消息队列的许可权等。msgctl的语法格式为:nint msgctl(msgid,cmd,buf);nint msgid,cmd;nstruct msgid_ds *buf;n其中,buf是用户缓冲区地址,供用户存放控制参数和查询结果;cmd是规定的命令。 共享存储区n共享存储区可使若干进程共享主存中的某一个区域,且使该区域出现在多个进程的虚地址空间中。n当进程间欲利用共享存储区进行通信时,必须首先在主存中建立一个共享存储区,然后将它附接到自己的虚地址空间上。n此后,进程对该区的访问操作,与对其虚地址空间中其他部分的操作完全相同。进程之间以后便可以通过对共享存储区中数据的读/写来进行直接通信。两进程通过共享存储区通信的例子 进程A的虚空间内存空间进程B的虚空间栈 共享存储区B正文数据栈正文数据AAB共享存储区的建立共享存储区的建立n系统调用shmget建立一个共享存储区。如果该共享存储区已由其他进程建立,则返回其描述符shmid。shmget的语法说明如下:nint shmget(key,size,shmflg);nkey_t key;nint size,shmflg;n其中,key是共享存储区的名字;size是其大小;shmflg是用户设置的标志,如IPC_CREAT,表示若系统中尚无指名的共享存储区则由核心建立一个共享存储区;若系统中已有该共享存储区,便忽略IPC_CREAT。共享存储区的附接共享存储区的附接n系统调用shmat( )将共享存储区附接到进程的虚地址空间上。该系统调用的语法格式如下:nchar *shmat(shmid,shmaddr,shmflg);nint shmid,shmflg;nchar *shmaddr;n其中,shmaddr是用户想要使共享存储区附接到的进程虚地址, shmflg是共享存储区的读写标志。n该系统调用的返回值是共享存储区所附接到的进程虚地址。共享存储区的断接共享存储区的断接n系统调用shmdt( )将共享存储区与进程断接。其语法格式如下:nint shmdt(shmaddr);nchar *shmaddr;n其中,shmaddr是要断接的虚地址,即以前由系统调用shmat( )所返回的虚地址。共享存储区的操纵共享存储区的操纵n系统调用shmctl( ) 对共享存储区的状态信息进行读取和修改。当所有进程都与共享存储区断接时,便可以删除该共享存储区。shmctl系统调用的语法格式为:nint shmctl(shmid,cmd,buf);nint shmid,cmd;nstruct shmid_ds, *buf;n其中,buf是用户缓冲区地址,cmd是操作命令。信号量nUNIX System 中采用的是信号量集机制,即由一组信号量构成的信号量数组。n传统的信号量机制是对信号量施加P和V操作,而UNIX System 中利用semop( )系统调用来对指定信号量进行操作。信号量集的建立信号量集的建立n系统调用semget( )建立信号量集。其语法格式如下:n int semget(key,nsems,semflg);n key_t key;n int nsems,semflg;n其中,key是信号量集的名字;nsems定义了信号量集中信号量的数目;而semflg的含义与msgget系统调用中的msgflg含义相同。系统调用的返回值是信号量集的描述符。 信号量集的操纵信号量集的操纵n系统调用semop( ) 对信号量数组进行操作。其语法格式为:nint semop(semid,sops,nsops);nint semid;nstruct sembuf * *sops;nunsigned nsops;n其中,semid是semget( )返回的描述符;sops是指向信号量操作结构数组的指针;nsops是该数组的大小。信号量集的操纵信号量集的操纵struct sembufshort sem_num;short sem_op;short sem_flg;
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号