Chinaunix首页 | 论坛 | 博客
  • 博客访问: 356728
  • 博文数量: 120
  • 博客积分: 4010
  • 博客等级: 上校
  • 技术积分: 1810
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-11 17:50
文章分类

全部博文(120)

文章存档

2008年(120)

我的朋友

分类:

2008-03-19 09:37:18

1.进程之间互相通讯并和核心通讯,协调它们的行为。 Linux 支持一些进程间通讯( IPC )的机制。信号和管道是其中的两种, Linux 还支持系统 V IPC (用首次出现的 Unix 的版本命名)的机制。
 
2.信号是 Unix 系统中使用的最古老的进程间通讯的方法之一。用于向一个或多个进程发送异步事件的信号。信号可以用键盘终端产生,或者通过一个错误条件产生,比如进程试图访问它的虚拟内存中不存在的位置。 Shell 也使用信号向它的子进程发送作业控制信号。
 
3. Linux 用进程的 task_struct 中存放的信息来实现信号机制。支持的信号受限于处理器的字长。 32 位字长的处理器可以有 32 中信号,而 64 位的处理器,比如 Alpha AXP 可以有多达 64 种信号。当前待处理的信号放在 signal 域, blocked 域放着要阻塞的信号掩码。除了 SIGSTOP 和 SIGKILL ,所有的信号都可以被阻塞。如果产生了一个被阻塞的信号,它一直保留待处理,直到被解除阻塞。 Linux 也保存每一个进程如何处理每一种可能的信号的信息,这些信息放在一个 sigaction 的数据结构数组中,每一个进程的 task_struct 都有指针指向对应的数组。这个数组中包括处理这个信号的例程的地址,或者包括一个标志,告诉 Linux 该进程是希望忽略这个信号还是让核心处理。进程通过执行系统调用改变缺省的信号处理,这些调用改变适当的信号的 sigaction 和阻塞的掩码。
 
4.并非系统中所有的进程都可以向其他每一个进程发送信号,只有核心和超级用户可以。普通进程只可以向拥有相同 uid 和 gid 或者在相同进程组的进程发送信号。通过设置 task —— struct 的 signal 中适当的位产生信号。如果进程不阻塞信号,而且正在等待但是可以中断(状态是 Interruptible ),那么它的状态被改为 Running 并确认它在运行队列,通过这种方式把它唤醒。这样调度程序在系统下次调度的时候会把它当作一个运行的候选。如果需要缺省的处理, Linux 可以优化信号的处理。例如如果信号 SIGWINCH ( X window 改变焦点)发生而使用缺省的处理程序,则不需要做什么事情。

    信号产生的时候不会立刻出现在进程中,它们必须等到进程下次运行。每一次进程从系统调用中退出的时候都要检查它的 signal 和 blocked 域,如果有任何没有阻塞的信号,就可以发送。这看起来好像非常不可靠,但是系统中的每一个进程都在调用系统调用,比如向终端写一个字符的过程中。如果愿意,进程可以选择等待信号,它们挂起在 Interruptible 状态,直到有了一个信号。 Linux 信号处理代码检查 sigaction 结构中每一个当前未阻塞的信号。

    如果信号处理程序设置为缺省动作,则核心会处理它。 SIGSTOP 信号的缺省处理是把当前进程的状态改为 Stopped ,然后运行调度程序,选择一个新的进程来运行。 SIGFPE 信号的缺省动作是让当前进程产生 core ( core dump ),让它退出。变通地,进程可以指定自己的信号处理程序。这是一个例程,当信号产生的时候调用而且 sigaction 结构包括这个例程的地址。 Linux 必须调用进程的信号处理例程,至于具体如何发生是和处理器相关。但是,所有的 CPU 必须处理的是当前进程正运行在核心态,并正准备返回到调用核心或系统例程的用户态的进程。解决这个问题的方法是处理该进程的堆栈和寄存器。进程程序计数器设为它的信号处理程序的地址,例程的参数加到调用结构或者通过寄存器传递。当进程恢复运行的时候显得信号处理程序是正常的调用。

    Linux 是 POSIX 兼容的,所以进程可以指定调用特定的信号处理程序的时候要阻塞的信号。这意味着在调用进程的信号处理程序的时候改变 blocked 掩码。信号处理程序结束的时候, blocked 掩码必须恢复到它的初始值。因此, Linux 在收到信号的进程的堆栈中增加了对于一个整理例程的调用,把 blocked 掩码恢复到初始值。 Linux 也优化了这种情况:如果同时几个信号处理例程需要调用的时候,就在它们堆积在一起,每次退出一个处理例程的时候就调用下一个,直到最后才调用整理例程。

5.管道是单向的字节流,把一个进程的标准输出和另一个进程的标准输入连接在一起。没有一个进程意识到这种重定向,和它平常一样工作。是 shell 建立了进程之间的临时管道。在 Linux 中,使用指向同一个临时 VFS I 节点(本身指向内存中的一个物理页)的两个 file 数据结构来实现管道。图 5.1 显示了每一个 file 数据结构包含了不同的文件操作例程的向量表的指针:一个用于写,另一个从管道中读。这掩盖了和通用的读写普通文件的系统调用的不同。当写进程向管道中写的时候,字节拷贝到了共享的数据页,当从管道中读的时候,字节从共享页中拷贝出来。 Linux 必须同步对于管道的访问。必须保证管道的写和读步调一致,它使用锁、等待队列和信号( locks , wait queues and signals )。

阅读(719) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~