11、FreeBSD的实现
经过学习我们对进程,进程组,会话,控制终端的属性有了一个定的了解,如果能够了解一下它们是怎么实现的也是很不错的。我们简单地看一下在Free BSD上面的实现。下面给出了一个图形展示FreeBSD使用的各种数据结构以及相应的关系。
FreeBSD中的会话和进程组的实现
session structure
---------------------->+--------+
tty structure / +-->|s_count |
+---------+<---------------------- | +--------+
| | / \| |s_leader|---+
+---------+ / \ +--------+ |
|t_session|/ |\ |s_ttyvp |\ |
+---------+ | \ +--------+ \ | v-node structure
|t_pgrp |\ foreground | \|s_ttyp | -+-->+----------+
+---------+ \process group | +--------+ | | |
|t_termios| \ pgrp structure | |s_sid | | +----------+
+---------+ ------>+----------+ | +--------+ | | actual |
|t_winsize| +---->| | | | | i-node |
+---------+ | +-->| | | | |for device|
| | | | +>+----------+ | | +----------+
+---------+ | | | |pg_id | | |
| | | +----------+ / |
| | | |pg_session|/ |
linked list of | | | +----------+ |
+----------------+-+-+>|pg_members| +----------+
| process group | | | +----------+ |
| members | | | |
| | | | |
| proc structure| | | proc structure \ proc structure
| +--------+ | | | +--------+ ----->+--------+
+--->|p_pglist|<-+-+-+----->|p_pglist|<---------->|p_pglist|
+--------+ | | | +--------+ +--------+
|p_pid | | | | |p_pid | |p_pid |
+--------+ | | | +--------+ +--------+
|p_pptr | | | | |p_pptr | |p_pptr |
+--------+ | | | +--------+ +--------+
| | | | | | | | |
+--------+ | | | +--------+ +--------+
|p_pgrp |--+ | +------|p_pgrp | /|p_pgrp |
+--------+ | +--------+ / +--------+
| | | | | / | |
+--------+ | +--------+ / +--------+
| /
+-------------------------
总共就5个结构:session结构,tty结构,pgrp结构,proc结构,vnode结构。
(1)session结构包含如下成员:
- s_count表示这个会话中进程组的数目。如果值为0那么会将此session结构释放。
- s_leader指针指向session leader进程的proc结构。
- s_ttyvp指针指向控制终端的vnode节点结构。
- s_ttyp指针指向控制终端的tty结构。
- s_sid是session ID,注意这个session ID并不是UNIX Specification中的概念。
当setsid被调用的时候,在内核中会创建一个新的session结构,这时候,s_count被设置为1,s_leader就指向调用setsid的进程的proc结构,s_sid设置为相应的进程id,s_ttyvp和s_ttyp设置成空指针,所以这个新的session没有控制终端。
(2)对于tty结构,内核包含这个结构,用于终端设备和伪终端设备。
tty结构包含的成员如下:
- t_session指向以本terminal为控制终端的session结构(注意session结构中也有指向本tty结构的指针)。当终端失去carrier(什么是carrier???)的时候,terminal通过这个指针给session leader发送hang-up信号。
- t_pgrp指针指向前台进程组的pgrp结构。通过这个成员,terminal driver给前台进程组发送信号。通过特殊按键产生的三个信号(interrupt,quit,suspend)就发送给了前台进程。
- t_termios是包含了这个终端的所有特殊字符以及相关信息的结构,信息例如波特率,是否echo on或者off等。
- t_winsize是一个winsize结构,包含了当前terminal窗口的大小,当terminal窗口大小发生变化的时候,会给前台进程发送一个SIGWINCH信号。以后会讲述如何设置和获取当前terminal的大小。
需要注意的是,为了找到一个会话的前台进程组,内核需要从session结构开始,通过s_ttyp找到控制终端的tty结构,然后通过t_pgrp获取前台进程组的pgrp结构。
(3)pgrp结构包含了一个特定的进程组的一些信息,其成员有:
- pg_id是进程组ID.
- pg_session指针指向进程组所在session的session结构。
- pg_members是一个指向prog结构的链表,其中的元素本进程组中的进程成员。相应地在proc结构中,有一个p_pglist结构,它是一个双向链表。指向组中下一个和上一个进程。
(4)proc结构包含一个单个进程所有的信息,其成员有:
- p_pid包含进程id。
- p_pptr是指向父进程proc结构的指针。
- p_pgrp指针指向该进程所属的进程组的pgrp结构。
- p_pglist是包含proc结构的双向链表,这个链表元素是和本进程同组的进程。
(5)最后,我们看看vnode结构
这个结构在控制终端被打开的时候分配,进程中所有/dev/tty的引用都会通过这个vnode结构。实际的i-node是v-node的一部分。
译者注
原文参考
12、总结
本章已经讲述了进程组之间的关系:会话,会话由进程组构成。作业控制是目前多数UNIX系统提供的一个特性,我们已经讲述了如何通过支持作业控制的shell来实现作业控制。进程的控制终端,/dev/tty也在讨论这些进程关系的时候有所涉及。
我们在谈到这些进程关系的时候,引用了大量的信号相关的概念,下一章,将会继续讲述这些信号概念,并且对UNIX系统中的信号机制做详细地讲述。
网友评论