
unix进程组,会话和作业控制.docx
13页UNIX 进程组,会话和作业控制2011-07-23 0 个评论 收藏 我要投稿 1. 进程组、会话与终端(1).每个进程都属于一个进程组进程组是一个或多个进程的集合,通常它们与一组作业相关联,可以接受来自同一终端的各种信号每个进程组都有唯一的进程组 ID(整数,也可以存放在 pid_t 类型中)include pid_t getpgrp(void);//返回值;调用进程的进程组 ID每个进程组都有一个组长进程,组长进程的标识是进程组 ID 等于其进程ID组长进程可以创建一个进程组、创建该组中的进程只有某个进程中有一个进程存在,则该进程就存在,与组长进程是否终止无关从进程组创建开始到其中最后一个进程离开为止的时间区间成为进程组的生存期进程组中最后一个进程可以终止或者转移到另一个进程组中进程调用 setpgid(setsid 也可以)可以参加一个现存的组或者创建一个新进程组#include #include int setpgid(pid_t pid, pid_t pgid);//返回:若成功则为 0,出错为-1这将 pid 进程的进程组 ID 设置为 pgid。
如果 pid 是 0,则使用调用者的进程 ID另外,如果 pgid 是 0,则由 pid 指定的进程 ID 被用作为进程组 ID如果这两个参数相等,则由 pid 指定的进程变成进程组组长一个进程只能为它自己或它的子进程设置进程组 I D在它的子进程调用了 exec 后,它就不再能改变该子进程的进程组 I D在大多数作业控制 shell 中,在 fork 之后调用此函数,使父进程设置其子进程的进程组 ID,然后使子进程设置其自己的进程组 ID这些调用中有一个是冗余的,但这样做可以保证父、子进程在进一步操作之前,子进程都进入了该进程组否则依赖于哪一个进程先执行,就产生一个竞态条件2).session 是一个或多个进程组的集合例如,在 shell 中:$proc1 | proc2 &$proc3 | proc4 那么此时,session 中就会有三个进程组存在,分别是{登陆 shell(session leader)},{proc1, proc2}, {proc3, proc4} 进程调用 setsid 函数就可建立一个新对话期include #include pid_t setsid(void);如果调用此函数的进程不是一个进程组的组长,则此函数创建一个新对话期,结果为:(a) 此进程变成该新对话期的对话期首进程(session leader,对话期首进程是创建该对话期的进程)。
此进程是该新对话期中的唯一进程b) 此进程成为一个新进程组的组长进程新进程组 ID 是此调用进程的进程IDc) 此进程没有控制终端如果在调用 setsid 之前此进程有一个控制终端,那么这种联系也被解除如果此调用进程已经是一个进程组的组长,则此函数返回出错为了保证不处于这种情况,通常先调用 fork,然后使其父进程终止,而子进程则继续因为子进程继承了父进程的进程组 ID,而其进程 ID 则是新分配的,两者不可能相等,所以这就保证了子进程不是一个进程组的组长对话期和进程组有一些其他特性:• 一个对话期可以有一个单独的控制终端(controlling terminal)这通常是我们在其上登录的终端设备(终端登录情况)或伪终端设备(网络登录情况)• 建立与控制终端连接的对话期首进程,被称之为控制进程(controlling process)• 一个对话期中的几个进程组可被分成一个前台进程组(foreground process group)以及一个或几个后台进程组(background process group)前台进程组接受终端输入信号Shell 中的作业控制就是对前后台进程组的控制,&或 Ctrl+Z 的进程组就是后台进程组。
• 如果一个对话期有一个控制终端,则它有一个前台进程组,其他进程组则为后台进程组• 无论何时键入中断键(常常是 DELETE 或 Ctrl-C)或退出键(常常是Ctrl-\),就会造成将中断信号或退出信号送至前台进程组的所有进程• 终端的挂断信号送至控制进程(对话期首进程• 系统在登陆时将自动建立控制终端如何分配一个控制终端依赖于实现在 open 时,有几个和控制终端相关的选项:O_NOCTTY 如果要打开的文件为终端机设备时,则不会将该终端当成进程控制终端有时不管标准输入、标准输出是否重新定向,程序都要与控制终端交互作用保证程序读写控制终端的方法是打开文件/dev/tty,在内核中,此特殊文件代表控制终端如果程序没有控制终端,则打开此设备将失败注意:控制终端只有一个,通常控制终端/dev/tty 代表当前 shell 的控制终端,其实是一个指向实际终端设备的连接实际的终端设备可能是tty1,ttyS1 或者 pst/1.(3).控制终端与终端首先介绍两个抽象概念:tty(终端设备的统称):tty 一词源于 Teletypes,或者teletypewriters,原来指的是电传打字机,是通过串行线用打印机键盘通过阅读和发送信息的东西,后来这东西被键盘与显示器取代,所以现在叫终端比较合适。
终端是一种字符型设备,它有多种类型,通常使用 tty 来简称各种类型的终端设备pty(伪终端,虚拟终端):远程 telnet 到主机或使用 xterm 时不也需要一个终端交互在 Linux 系统的设备特殊文件目录/dev/下,终端特殊设备文件一般有以下几种:1、串行端口终端(/dev/ttySn) 串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备计算机把每个串行端口都看作是一个字符设备有段时间这些串行端口设备通常被称为终端设备,因为那时它的最大用途就是用来连接终端2、伪终端(/dev/pty/) 伪终端(Pseudo Terminal)是成对的逻辑终端设备(即 master 和 slave 设备, 对 master 的操作会反映到 slave 上)例如/dev/ptyp3 和/dev/ttyp3(或者在设备文件系统中分别是/dev/pty /m3 和/dev/pty/s3)它们与实际物理设备并不直接相关如果一个程序把ptyp3(master 设备)看作是一个串行端口设备,则它对该端口的读/ 写操作会反映在该逻辑终端设备对应的另一个 ttyp3(slave 设备)上面。
而 ttyp3 则是另一个程序用于读写操作的逻辑设备telnet 主机 A 就是通过“伪终端”与主机 A 的登录程序进行通信3、控制终端(/dev/tty) 如果当前进程有控制终端(Controlling Terminal)的话,那么/dev/tty 就是当前进程的控制终端的设备特殊文件可以使用命令”ps –ax”来查看进程与哪个控制终端相连对于你登录的shell,/dev/tty 是你当前的控制终端,设备号是(5,0)使用命令”tty”可以查看它具体对应哪个实际终端设备/dev/tty 有些类似于到实际所使用终端设备的一个联接在当前的控制终端的读写都会写到当前的终端设备中,例如 echo "hello" > /dev/tty ,都会直接显示在当前的终端中而 cat #include int tcgetattr(int fd, struct termios *termios_p); //成功则返回与终端文件描述符 fd 相关联的前台进程的组 ID,出错则返回-1int tcsetattr(int fd, int optional_actions, const struct termios *termios_p); //成功则返回 0,出错则返回-1//struct termios 定义一和终端相关的标识字段,例忽略 BREAK 键,忽略校验等等。
大多数应用程序不直接调用这两个函数,它们通常由作业控制 shell 调用2. 作业控制(1).允许在一个终端上起动多个作业(进程组),控制哪一个作业可以存取该终端,以及哪些作业在后台运行作业控制要求三种形式的支持:(a).支持作业控制的 shellb).内核中的终端驱动程序必须支持作业控制c).必须提供对某些作业控制信号的支持三个特殊字符可使终端驱动程序产生信号,并将它们送至前台进程组,它们是:• 中断字符(一般采用 DELETE 或 Ctrl-C)产生 SIGINT• 退出字符(一般采用 Ctrl-\)产生 SIGQUIT• 挂起字符(一般采用 Ctrl-Z)产生 SIGTSTP2).不支持作业控制的 Shell对于不支持作业控制的 Shell,例如 bsh,它的命令和它自身的进程处于同一个会话和前台进程组在后台执行的命令(&)和管道命令的进程依然和 Shell 是同一个进程组如果一个后台进程试图取走终端,例如 cat > temp &在有作业控制时,后台作业被放在后台进程组中如果后台作业试土读控制终端,则会产生信号SIGTTIN在没有作业控制时,其处理方法是如果该进程自己没有重定向标准输入,则 Shell 会自动将标准输入重定向到/dev/null。
读/dev/null 则会产生一个 EOF让 cat 读到文件末尾,正常结束另外,管道执行的结构图如下:(3).支持作业控制的 Shell$ ps -o pid -o ppid -o sid -o pgid -o commandPID PPID SID PGID COMMAND2074 2068 2074 2074 /bin/bash2580 2074 2074 2580 ps -o pid -o ppid -o sid -o pgid -o command可以看出它们有不同的 PGID对于管道命令,他们属于同一个进程组:$ ps -o pid -o ppid -o sid -o pgid -o command | catPID PPID SID PGID COMMAND2074 2068 2074 2074 /bin/bash 2584 2074 2074 2584 ps -o pid -o ppid -o sid -o pgid -o command2585 2074 2074 2584 cat(4).SIGHUP 信号SIGHUP 会在以下 3 种情况下被发送给相应的进程:1、终端关闭时,该信号被发送到 session 首进程以及作为 job 提交的进程(即用& 符号提交的进程)2、session 首进程退出时,该信号被发送到该 session 中的前台进程组中的每一个进程3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到 SIGTSTP 信号),SIGHUP 会被发送到该进程组中的每一个进程。
系统对 SIGHUP 信号的默认处理是终止收到该信号的进程所以若程序中没有捕捉该信号,当收到该信号时,进程就会退出If a controlling process exits, the system revokes further access to the controlling terminal and sends a SIGHUP signal to the foreground process group. If a process such as a job-control shell exits, each process group that it created will become an orphaned process group5).bash 作业控制命令(a). nohup:使用 nohup 让程序永远后台运行由。
