如果信号的处理过程被设置成缺省则由核心来应付它 。SIGSTOP信号的缺省处理过程是将当前进程的状态改变成为Stopped并运行调度管理器以选择一个新进程继续运行 。SIGFPE的缺省处理过程则是引起core dump并使进程退出 。当然 , 进程可以定义其自身的信号处理过程 。一旦信号产生 , 这个过程就将被调用 。它的地址存储在sigaction结构中 。核心必须调用进程的信号处理例程 , 具体如何去做依赖于处理器类型 , 但是所有的CPU 必须处理这个问题:如果信号产生时 , 当前进程正在核心模式下运行并且马上要返回调用核心或者系统例程的进程 , 而该进程处在用户模式下 。解决这个问题需要操纵进程的堆栈及寄存器 。进程的程序计数器被设置成其信号处理过程的地址 , 而参数通过调用框架或者寄存器传递到处理例程中 。当进程继续执行时 , 信号处理例程好象普通的函数调用一样 。
Linux是POSIX兼容的 , 所以当某个特定信号处理例程被调用时 , 进程可以设定哪个信号可以阻塞 。这意味着可以在进程信号处理过程中改变blocked屏蔽码 。当信号处理例程结束时 , 此blocked屏蔽码必须设置成原有值 。因此 , Linux添加了一个过程调用来进行整理工作 , 通过它来重新设置被发送信号进程调用栈中的原有blocked屏蔽码 。对于同一时刻几个信号处理过程 , Linux通过堆栈方式来优化其使用 , 每当一个处理过程退出时 , 下一个处理过程必须等到整理例程结束后才执行 。
5.2管道
一般的Linux shell程序都允许重定向 。如
$ ls | pr | lpr
在这个管道应用中 , ls列当前目录的输出被作为标准输入送到pr程序中 , 而pr的输出又被作为标准输入送到lpr程序中 。管道是单向的字节流 , 它将某个进程的标准输出连接到另外进程的标准输入 。但是使用管道的进程都不会意识到重定向的存在 , 并且其执行结果也不会有什么不同 。shell程序负责在进程间建立临时的管道 。
图5.1 管道
在Linux中 , 管道是通过指向同一个临时VFS inode的两个file数据结构来实现的 , 此VFS inode指向内存中的一个物理页面 。图5.1中每个file数据结构指向不同的文件操作例程向量 , 一个是实现对管道的写 , 另一个从管道中读 。
这样就隐藏了读写管道和读写普通的文件时系统调用的差别 。当写入进程对管道写时 , 字节被拷贝到共享数据页面中 , 当读取进程从管道中读时 , 字节从共享数据页面中拷贝出来 。Linux必须同步对管道的访问 。它必须保证读者和写者以确定的步骤执行 , 为此需要使用锁、等待队列和信号等同步机制 。
当写者想对管道写入时 , 它使用标准的写库函数 。表示打开文件和打开管道的描叙符用来对进程的file数据 结构集合进行索引 。Linux系统调用使用由管道file数据结构指向的write过程 。这个write过程用保存在表示管道的VFS inode中的信息来管理写请求 。
如果没有足够的空间容纳对所有写入管道的数据 , 只要管道没有被读者加锁 。则Linux为写者加锁 , 并把从写入进程地址空间中写入的字节拷贝到共享数据页面中去 。如果管道被读者加锁或者没有足够空间存储数据 , 当前进程将在管道inode的等待队列中睡眠 , 同时调度管理器开始执行以选择其它进程来执行 。如果写入进程是可中断的 , 则当有足够的空间或者管道被解锁时 , 它将被读者唤醒 。当数据被写入时 , 管道的VFS inode被解锁 , 同时任何在此inode的等待队列上睡眠的读者进程都将被唤醒 。
从管道中读出数据的过程和写入类似 。
推荐阅读
- Linux 核心--5.Linux进程
- 网卡设置指南
- Linux下构架qmail邮件系统
- linux的运行模式:runlevel
- 用 Linux 打造路由器
- Linux 和 Windows 共享交换区
- Linux下的常用软件列表
- 优化Linux系统硬盘的七个实用技巧
- Linux系统中提取DVD音频的方法介绍
- 在Linux中如何提高文件系统的使用效率
