分类: 系统运维
2012-03-30 18:31:58
我们已经谈过一个进程、进程组、会话和控制终端的各种属性,现在值得看下这些是如何实现的。我们将简明地看下FreeBSD使用的实现方式。SVR4上这些特性的实现的一些细节可以在Williams[1989]里找到。下表显示了FreeBSD使用的各种数据结构:
让我们看看我们标出的所有的域,从session结构体开始。每个会话都会分配一个这样的结构体(例如,每次setsid被调用时)。
1、s_count是会话里的进程组数量。当这个数量被减为0时,结构体会被释放。
2、s_leader是会话领导的proc结构体的指针。
3、s_ttyvp是控制终端的v-node结构体的指针。
4、s_ttyp是控制终端的tty结构体的指针。
5、s_sid是会话ID。回想下会话ID的概念不是SUS的一部分。
当setsid被调用时,一个新的session结构体在内核里被分配。现在s_count被设为1,s_leader被设为调用进程的proc结构体的指针,s_sid被设置成进程ID,s_ttyvp和s_ttyp被设为空指针,因为新的会话没有一个控制终端。
让我们移到tty结构体。内核为每个终端设备和伪终端设备包含一个这样的结构体。(我们将在19章更多讨论伪终端。)
1、t_session指向把这个终端作为它的控制终端的会话结构体。(注意tty结构体指向session结构体,反过来也是这样。)这个指针被终端用来向会话领导发送挂起信号,如果终端失去了I/O(比如网络断开连接)。
2、t_pgrp指向前台进程组的pgrp结构体。这个域被终端驱动器用来向前台进程组发送信号。通过输入特殊字符产生的三个信号(中断、退出和挂起)被发送给前台进程组。
3、t_termios是一个结构体,包含所有特殊字符,和这个终端相关的信息,比如波特率,回声是否被打开,等等。我们将在18章回到这个结构体。
4、t_winsize是一个winsize结构体,包含终端窗口的当前尺寸。当终端窗口的尺寸改变时,SIGWINCH信号被发送给前台进程组。我们将在18.12节显示如何设置和获取终端的当前窗口尺寸。
注意为了找到特定会话的前台进程组,内核必须从会话结构体开始,跟随s_ttyp来得到控制终端的tty结构体,然后跟随t_pgrp来得到前台进程组的pgrp结构体。pgrp结构体包括一个特定进程组的信息。
1、pg_id为进程组ID。
2、pg_session指向该进程组所属的会话的session结构体。
3、pg_members是指向该进程组成员的proc结构体列表的指针。在proc结构体里的p_pglist结构体是一个双向链表项,指向组里的前一个和后一个进程,等等,直到在进程组里的最后的进程的proc结构体里碰到一个空指针。
proc结构体包含单个进程的所有信息。
1、p_pid包含进程ID。
2、p_pptr是指向父进程的proc结构体的一个指针。
3、p_pgrp指向这个进程所属的进程组的pgrp结构体。
4、p_pglist是一个结构体,包含进程组里的前一个和后一个进程的指针,如我们之前提到的。
最后,我们有vnode结构体。这个结构体在控制终端被打开时被分配。一个进程里的所有/dev/tty的引用都经过这个vnode结构体。我们展示了真实i-node是v-node的一部分。