进程间通讯机制

上传人:博****1 文档编号:564725269 上传时间:2022-10-30 格式:DOC 页数:10 大小:299KB
返回 下载 相关 举报
进程间通讯机制_第1页
第1页 / 共10页
进程间通讯机制_第2页
第2页 / 共10页
进程间通讯机制_第3页
第3页 / 共10页
进程间通讯机制_第4页
第4页 / 共10页
进程间通讯机制_第5页
第5页 / 共10页
点击查看更多>>
资源描述

《进程间通讯机制》由会员分享,可在线阅读,更多相关《进程间通讯机制(10页珍藏版)》请在金锄头文库上搜索。

1、进程间通讯机制进程在核心的协调下进行相互间的通讯。 Linux 支持大量进程间通讯 (IPC) 机制。除了信号和管道外,Linux还支持Unix系统V中的IPC机制。信号是 Unix 系统中的最古老的进程间通讯方式。它们用来向一个或多个进程发 送异步事件信号。 信号可以从键盘中断中产生, 另外进程对虚拟内存的非法存取 等系统错误环境下也会有信号产生。 信号还被 shell 程序用来向其子进程发送任 务控制命令。系统中有一组被详细定义的信号类型, 这些信号可以由核心或者系统中其它具有 适当权限的进程产生。使用kill命令(kill -I)可以列出系统中所有已经定义的 信号。在我的系统 (Inte

2、l 系统)上运行结果如下:1) SIGHUP2) SIGINT3) SIGQUIT4) SIGILL5) SIGTRAP6) SIGIOT7) SIGBUS8) SIGFPE9) SIGKILL10) SIGUSR111) SIGSEGV12) SIGUSR213) SIGPIPE14) SIGALRM15) SIGTERM17) SIGCHLD18) SIGCONT19) SIGSTOP20) SIGTSTP21) SIGTTIN22) SIGTTOU23) SIGURG24) SIGXCPU25) SIGXFSZ26) SIGVTALRM27) SIGPROF28) SIGWINCH29)

3、 SIGIO30) SIGPWR当我在Alpha AXP中运行此命令时,得到了不同的信号个数。除了两个信号外, 进程可以忽略这些信号中的绝大部分。其一是引起进程终止执行的SIGSTOP言号, 另一个是引起进程退出的SIGKILL信号。至于其它信号,进程可以选择处理它 们的具体方式。 进程可以阻塞信号, 如若不阻塞, 则可以在自行处理此信号和将 其转交核心处理之间作出选择。 如果由核心来处理此信号, 它将使用对应此信号 的缺省处理方法。 比如当进程接收到SIGFPE浮点数异常)时,核心的缺省操作 是引起core dump和进程的退出。信号没有固有的相对优先级。如果在同一时刻 对于一个进程产生了两

4、个信号,则它们将可能以任意顺序到达进程并进行处理。同时 Linux 并不提供处理多个相同类型信号的方式。 即进程无法区分它是收到了1个还是42个SIGCON信号。Linux 通过存储在进程 task_struct 中的信息来实现信号。 信号个数受到处理器 字长的限制。 32位字长的处理器最多可以有 32个信号而 64位处理器如 Alpha AXP 可以有最多 64 个信号。当前未处理的信号保存在 signal 域中,并带有保存在 blocked中的被阻塞信号的屏蔽码。除了 SIGSTO味口 SIGKILL外,所有的信号都 能被阻塞。 当产生可阻塞信号时, 此信号可以保持一直处于待处理状态直到阻

5、塞 释放。 Linux 保存着每个进程处理每个可能信号的信息,它们保存在每个进程 task_struct 中的 sigaction 数组中。 这些信息包括进程希望处理的信号所对应 的过程地址,或者指示是忽略信号还是由核心来处理它的标记。通过系统调用, 进程可以修改缺省的信号处理过程, 这将改变某个信号的 sigaction 以及阻塞屏 蔽码。并不是系统中每个进程都可以向所有其它进程发送信号: 只有核心和超级用户具 有此权限。普通进程只能向具有相同 uid 和 gid 的进程或者在同一进程组中的进 程发送信号。信号是通过设置 task_struct 结构中 signal 域里的某一位来产生 的。

6、如果进程没有阻塞信号并且处于可中断的等待状态,则可以将其状态改成 Running,同时如确认进程还处在运行队列中,就可以通过信号唤醒它。这样系 统下次发生调度时, 调度管理器将选择它运行。 如果进程需要缺省的信号处理过 程,则Linux可以优化对此信号的处理。例如 SIGWINCHX窗口的焦点改变)信 号,其缺省处理过程是什么也不做。信号并非一产生就立刻交给进程,而是必须等待到进程再次运行时才交给进程。 每次进程从系统调用中退出前,它都会检查 signal 和 blocked 域,看是否有可 以立刻发送的非阻塞信号。 这看起来非常不可靠, 但是系统中每个进程都在不停 地进行系统调用, 如向终端

7、输出字符。 当然进程可以选择去等待信号, 此时进程 将一直处于可中断状态直到信号出现。对当前不可阻塞信号的处理代码放置在 sigaction 结构中。如果信号的处理过程被设置成缺省则由核心来应付它。SIGSTOP言号的缺省处理过程是将当前进程的状态改变成为 Stopped 并运行调度管理器以选择一个新进 程继续运行。SIGFPE勺缺省处理过程则是引起core dump并使进程退出。当然, 进程可以定义其自身的信号处理过程。 一旦信号产生, 这个过程就将被调用。 它 的地址存储在 sigaction 结构中。核心必须调用进程的信号处理例程, 具体如何 去做依赖于处理器类型,但是所有的CPU必须处

8、理这个问题:如果信号产生时, 当前进程正在核心模式下运行并且马上要返回调用核心或者系统例程的进程, 而 该进程处在用户模式下。 解决这个问题需要操纵进程的堆栈及寄存器。 进程的程 序计数器被设置成其信号处理过程的地址, 而参数通过调用框架或者寄存器传递 到处理例程中。当进程继续执行时,信号处理例程好象普通的函数调用一样。Linux是POSIX兼容的,所以当某个特定信号处理例程被调用时,进程可以设定 哪个信号可以阻塞。这意味着可以在进程信号处理过程中改变 blocked 屏蔽码。 当信号处理例程结束时,此 blocked 屏蔽码必须设置成原有值。 因此, Linux 添加了一个过程调用来进行整理

9、工作, 通过它来重新设置被发送信号进程调用栈中的原有blocked屏蔽码。对于同一时刻几个信号处理过程,Linux通过堆栈 方式来优化其使用,每当一个处理过程退出时,下一个处理过程必须等到整理例 程结束后才执行。管道般的Linux shell 程序都允许重定向。如$ Is | pr | lpr在这个管道应用中,ls列当前目录的输出被作为标准输入送到 pr程序中,而pr 的输出又被作为标准输入送到lpr程序中。管道是单向的字节流,它将某个进程 的标准输出连接到另外进程的标准输入。但是使用管道的进程都不会意识到重定 向的存在,并且其执行结果也不会有什么不同。shell程序负责在进程间建立临时的管道

10、。Prxm 2filefileP IpeWe iteOperationsPipeRe sriOpersti cm百i管道在 Linux 中,管道是通过指向同一个临时 VFS inode 的两个 file 数据结构来实 现的,此VFS in ode指向内存中的一个物理页面。图 5.1中每个file 数据结构 指向不同的文件操作例程向量,一个是实现对管道的写,另一个从管道中读。这样就隐藏了读写管道和读写普通的文件时系统调用的差别。 当写入进程对管道 写时,字节被拷贝到共享数据页面中, 当读取进程从管道中读时, 字节从共享数 据页面中拷贝出来。 Linux 必须同步对管道的访问。它必须保证读者和写者

11、以确 定的步骤执行,为此需要使用锁、等待队列和信号等同步机制。当写者想对管道写入时, 它使用标准的写库函数。 表示打开文件和打开管道的描 叙符用来对进程的 file 数据 结构集合进行索引。 Linux 系统调用使用由管道 file 数据结构指向的 write 过程。这个 write 过程用保存在表示管道的 VFSinode 中的信息来管理写请求。如果没有足够的空间容纳对所有写入管道的数据, 只要管道没有被读者加锁。 则 Linux 为写者加锁, 并把从写入进程地址空间中写入的字节拷贝到共享数据页面 中去。如果管道被读者加锁或者没有足够空间存储数据,当前进程将在管道 inode 的等待队列中睡

12、眠,同时调度管理器开始执行以选择其它进程来执行。如 果写入进程是可中断的, 则当有足够的空间或者管道被解锁时, 它将被读者唤醒。 当数据被写入时,管道的 VFSinode 被解锁,同时任何在此 inode 的等待队列上 睡眠的读者进程都将被唤醒。从管道中读出数据的过程和写入类似。进程允许进行非阻塞读 (这依赖于它们打开文件或者管道的方式) ,此时如果没 有数据可读或者管道被加锁, 则返回错误信息表明进程可以继续执行。阻塞方 式则使读者进程在管道 inode 的等待队列上睡眠直到写者 进程结束。当两个进 程对管道的使用结束时,管道 inode 和共享数据页面将同时被遗弃。Linux还支持命名管道

13、(named pipe),也就是FIFO管道,因为它总是按照先进 先出的原则工作。第一个被写入 的数据将首先从管道中读出来。和其它管道不 一样,FIFO管道不是临时对象,它们是文件系统中的实体并且 可以通过mkfifo 命令来创建。进程只要拥有适当的权限就可以自由使用 FIFO管道。打开FIFO 管道的方式稍有不同。 其它管道需要先创建(它的两个 file 数据结构, VFSinode 和共享数据页面)而FIFO管道已经存在,只需要由使用者打开与关闭。在写者 进程打开它之前,Linux必须让读者进程先打开此 FIFO管道;任何读者进程从 中读取之前必须有写者进程向其写入数据。FIFO管道的使用

14、方法与普通管道基 本相同,同时它们使用相同数据结构和操作。套接口系统 V IPC 机制Linux支持Unix系统V( 1983)版本中的三种进程间通讯机制。它们是消息队列、 信号灯以及共享内存。这些系统 VIPC机制使用共同的授权方法。只有通过系统 调用将标志符传递给核心之后,进程才能存取这些资源。这些系统VIPC对象使用与文件系统非常类似的访问控制方式。对象的引用标志符被用来作为资源表中 的索引。这个索引值需要一些处理后才能得到。系统中所有系统V IPC对象的Linux数据结构包含一个ipc_perm结构,它含有 进程拥有者和创建者及组标志符。另外还有对此对象(拥有者,组及其它)的存 取模式

15、以及IPC对象键。此键值被用来定位系统 VIPC对象的引用标志符。这样 的键值一共有两组:公有与私有。如果此键为公有,则系统中任何接受权限检查 的进程都可以找到系统 VIPC对象的引用标志符。系统 VIPC对象绝不能用一个 键值来引用,而只能使用引用标志符。消息队列消息队列允许一个或者多个进程向它写入与读取消息。Linux维护着一个msgque 消息队列链表,其中每个元素指向一个描叙消息队列的msqid_ds结构。当创建 新的消息队列时,系统将从系统内存中分配一个msqid_ds结构,同时将其插入到数组中。JTTEg um系统V IPC消息队列每个msqid_ds结构包含一个ipc_perm结

16、构和指向已经进入此队列消息的指针 另外,Linux保留有关队列修改时间信息,如上次系统向队列中写入的时间等。 msqid_ds包含两个等待队列:一个为队列写入进程使用而另一个由队列读取进 程使用。每次进程试图向写入队列写入消息时, 系统将把其有效用户和组标志符与此队列 的 ipc_perm 结构中的模式进行比较。如果允许写入操作,则把此消息从此进程 的地址空间拷贝到msg数据结构中,并放置到此消息队列尾部。由于 Linux严 格限制可写入消息的个数和长度, 队列中可能容纳不下这个消息。 此时, 此写入 进程将被添加到这个消息队列的等待队列中, 同时调用调度管理器选择新进程运 行。当由消息从此队列中释放时,该进程将被唤醒。从队列中读的过程与之类似。 进程对这个写

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号