第4章 进程同步与通信2

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

消息缓冲队列通信机制中的数据结构

消息缓冲区的数据结构如下: struct message { sender; 发送者进程标识符 size; 消息长度 text; 消息正文 next; 指向下一个消息缓冲区的指针 }
在PCB中还应增加
struct PCB { ┇ mq;消息队列队首指针 mutex;消息队列互斥信号量 sm;消息队列资源信号量 ┇ }
进程写管道

进程向管道写数据时,可能有以下两种情况:


管道中有足够的空间存放要写的数据,此时每写 一数据块后核心便自动增加地址项的大小。写操 作完成后,核心修改索引节点中的写指针,并唤 醒所有因该管道空而睡眠等待的读进程。 管道中无足够的空间存放要写入的数据,此时核 心对该索引节点作标记后让写进程睡眠,等待数 据从管道中排出。上述情况的一个例外是,当进 程写的数据量大于管道的容量时,核心将尽可能 多的数据写到管道中,然后使进程睡眠,直到获 得更多的空间。
消息


消息是一个格式化的可变长的信息单元。 消息机制允许进程向其他进程发送消息。 当一个进程收到多个消息时,可将这些 消息排成一个队列。 在UNIX中,消息机制向用户提供了四个 系统调用,分别用于建立、发送、接收 和管理消息。
消息机制的数据结构

UNIX的消息机制中使用了两种数据结构:


消息首部:消息首部中记录消息的类型、大小、 指向消息数据区的指针、消息队列的链接指针等。 消息队列头标:每个消息队列的消息头标中,包 含了指向消息队列中第一个消息的指针和指向最 后一个消息的指针,队列中消息的数目,队列中 消息数据的总字节数,队列所允许的消息数据的 最大字节总数,还可以含有最近一次执行发送操 作的进程标识号和时间等。
消息的接收

系统调用msgrcv( ) 从指定消息队列中接收指 定类型的消息,其语法格式如下:

int msgrcv (msgid, msgp, msgsz, msgtyp, msgflg); int msgid,msgsz,msgflg; struct msgbuf * msgp; long msgtyp;
信号的发送



信号的发送是指由发送进程把信号发送到指 定进程信号域的某一位上。 如果目标进程正在一个可被中断的优先级上 睡眠,核心便将它唤醒,发送过程就此结束。 一个进程可能在其信号域中有多个位被置位, 代表有多种类型的信号到达,但对于一类信 号,进程却只能记住其中的一个。
发送信号


系统调用kill向一个进程或一组进程发送一个 信号。该系统调用的语法格式如下: int kill(pid,sig); int pid,sig; 其中,sig是要发送的信号,pid参数是进程 标识号。 pid参数除了可以取进程标识号之 外,还可以取下列一些特殊值:
互斥:诸进程互斥读写管道 同步:管道空、满情况处理 存在:确定对方是否存在

共享文件通信示意图1

初始时,其长度为4,系统将管道看成一个循环 队列。按先进先出的方式读写。
A out B C D in

写入字符E后,管道长度为5
A B C D E
out
in
共享文件通信示意图2

读一个字符后,管道长度为4


func=1时,进程对信号sig不予理睬。 func=0时,即缺省处理,对大多数软中断信号的 缺省处理是终止进程。 func为其他整数值时,它的值是指向信号处理程 序的指针。
信号的处理

检查软中断信号的时机:

进入或退出低优先级睡眠状态 即将从核心态返回用户态
忽略 缺省处理,即终止进程 执行用户设置的软中断处理程序
B out C D E in

若管道容量为n且in=n时,再写入一 个字符,则in移到管道的另一端。
D E … X
in
out
习题



P79 2 6 7 14
UNIX的进程同步与通信P256

UNIX的早期版本中,为进程的同步与通信提供了:

软中断信号 管道机制

在UNIX SYSTEM Ⅴ中,推出了新的进程通信机构 IPC:
4.6 进程通信


进程通信是指进程之间的信息交换。 进程互斥与同步交换的信息量较少且效率 较低,因此称这两种进程通信方式为低级 进程通信方式,相应地也将P、V原语称为 两条低级进程通信原语。 高级进程通信方式是指进程之间以较高的 效率传送大量数据。
进程通信的类型

高级进程通信方式可分为三大类:
两个进程进行通信的过程
进程A send(B,a); ┇ a sender:A size:6 text:Hello! PCB(B) ┇ mq mutex sm
进程B
receive(b) ┇
b
sender:A
size:6
第一个消息缓冲区
sender:A size:6 text:Hello! next:0
消息传递系统


在消息传递系统中,进程间的数据交换以消 息为单位,程序员直接利用系统提供的一组 通信命令(原语)来实现通信。 消息传递系统因其实现方式不同可分为:


直接通信方式:发送进程将消息发送到接收进程, 并将其挂在接收进程的消息队列上;接收进程从 消息队列上取消息。 间接通信方式:发送进程将消息发送到信箱,接 收进程从信箱中取消息。

信箱通信原语包括:

信箱的创建和撤消: 消息的发送和接收:

Send(mailbox,message); Receive(mailbox,message);
3.共享文件


使用共享文件通信时,基本上采用文件 系统的原有机制实现。包括创建、打开、 关闭、读写等。 管道机制应提供以下三方面的协调能力:
text:Hello!
2.信箱通信



信箱通信方式中,进程之间通信需要通过共享 数据结构实体--信箱来进行。 信箱是一种数据结构,其中存放信件。 信箱逻辑上分成信箱头和信箱体两部分。

信箱头中存放有关信箱的描述。 信箱体由若干格子组成,每格存放一个信件,格 子的数目和大小在创建信箱时确定。
信箱通信原语
设置信号的处理方式



系统调用signal用于设置信号的处理方式。其 语法格式如下: void (* func)( ) signal(sig,func) 其中,func为收到软中断信号sig后进程希望 调用函数的地址。 19类信号如表所示。
func的取值情况

func的取值可以分成三种情况:

进程读管道


当进程从管道读数据时,同样会有两种情况:

管道中有足够的数据供进程读。此时,进程便从 读指针所指位置开始读数据,每读出一个数据块 后,便增加地址项的大小。读操作结束后,核心 修改索引节点中的读指针,并唤醒所有睡眠的写 进程。 进程要读的数据比管道中的数据多。此时,读进 程将返回管道中当前所有的数据。如果管道为空, 进程一般将进入睡眠,直到一个写进程将数据写 入管道,再将读进程唤醒。
共享文件(管道)通信

共享文件(管道)通过连接读进程和写进程 的共享文件来实现读写进程之间通信。
1.消息缓冲通信


消息缓冲通信是直接通信方式的一种实现。系 统通过两条通信原语Send及Receive进行通信。 为了实现消息通信,发送进程应先在自己的工 作区中设置一个发送区,把欲发送的消息填入 其中,然后再用发送原语将其发送出去。接收 进程调用接收原语从自己的消息缓冲队列中摘 下第一个消息,并将其内容复制到自己的消息 接收区内。
pipe文件的建立

pipe系统调用建立一个无名管道。其语法格式如下:

int pipe(fdes); int fdes[2]; 分配磁盘和内存索引节点。 为读进程和写进程分配文件表项。 分配用户文件描述符。在读进程和写进程的用户文件描述 符表中,分别分配一个表项,并将文件描述符fdes[0]和 fdes[1]分别返回给读进程和写进程。

核心创建一个管道时须完成下述工作:

Pipe涉及的数据结构
用户文件 描述符表 文件表

内存索引 节点表

外存


读进程 fp


写进程 fp
文件指针 文件指针

索引节点
PIPE文件



pipe文件的大小限制

pipe文件只使用索引节点中的直接地址项。 核心将索引节点中的直接地址项作为一个 循环队列来管理,为它设置一个读指针和 一个写指针,按先进先出顺序进行读和写。
其中,key是用户指定的消息队列的名字;msgflg是 用户设置的标志和访问方式。如IPC_CREAT表示系 统中若无以key命名的消息队列,则建立消息队列; 若该队列已存在,则返回该消息队列的描述符。
消息的发送

系统调用msgsnd( )向指定的消息队列发送一个消 息,并将发送消息链接到该消息队列的尾部。系统 调用的语法格式为:

共享存储器系统 消息传递系统 管道通信系统或共享文件系统
共享存储器系统

相互通信的进程共享某些数据结构或共享 存储区。


基于共享数据结构的通信方式:诸进程通过公 用某些数据结构交换信息。如生产者-消费者问 题。 基于共享存储区的通信方式:在存储器中划出 一块共享存储区,诸进程可通过对共享存储区 进行读或写来实现通信。包括建立共享存储区、 附接及断接。

消息机制 共享存储区机制 信号量机制
软中断信号



软中断信号(简称信号)是一种实现进程间 简单通信的设施,用于通知对方发生了异常 事件。 UNIX SYSTEM Ⅴ中,共有19个软中断信号。 软中断是对硬件中断的一种模拟,接收进程 在收到软中断信号后,将按照事先的规定去 执行一个软中断处理程序。 软中断处理程序必须等到接收进程执行时才 能生效。
发送原语描述
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; }

信号的处理方式:

管道


管道是指能连接某些读进程和写进程的、专 门用于进程通信的共享文件。 管道允许读/写进程按先进先出的方式传送 数据,即写进程从管道的一端向管道写入数 据,读进程从管道的另一端读出数据。
管道的类型

管道的类型有:

无名管道 有名管道

有名管道和无名管道的读写方式是相同的。
无名管道


无名管道是用系统调用pipe()建立的无名 文件,用该系统调用所返回的文件描述符 来标识该文件。 只有调用pipe的进程及其子孙进程才能利用 该管道文件进行通信。
有名管道



有名管道是利用mknod系统调用建立的,是 可以在文件系统中长期存在的具有路径名的 文件, 其他进程可以知道有名管道的存在并能利用 路径名来访问该文件。 对有名管道的访问方式象访问其他文件一样, 都需先用open系统调用去打开它。
pid参数特殊值



pid为0:表示把信号发送给与发送进程同组的所有进 程,也包括发送进程自己。 pid为 -1且发送进程的有效用户标识符不是超级用户: 表示把信号发送给其实际用户标识符与发送进程的 有效用户标识符相同的所有进程,也包括发送进程 本身在内。 pid为-1且发送进程的有效用户标识符为超级用户: 表示把信号发送给除了一些特殊系统进程之外的所 有进程。 pid是一个非-1的负数:表示把信号发送给组号为pid 绝对值的进程组中的所有进程。
消息和消息队列示意图
消息队列头标
消息首部 数据区


消息队列的建立和描述符的获取

在UNIX系统中,系统调用msgget用来建立消息队列 或者获取消息队列的描述符。该系统调用的语法格 式如下:

int msgget(key,msgflg); key_t key; int msgflg;


int msgsnd(msgid,msgp,msgsz,msgflg); int msgid,msgsz,msgflg; struct msgbuf *msgp;

其中,msgid是由msgget返回的消息队列描述符; msgp是指向用户消息缓冲区的指针。msgsz是消息 的长度,msgflg规定了当无内存空间存储消息时, 进程是等待还是立即返回。
相关文档
最新文档