2016-02-05
作业控制
作业控制允许一个终端上启动多个作业(进程组)控制哪一个作业可以存取该终端,已经哪些作业在后台运行。作业控制要求三种形式的支持。
- 支持作业控制的shell
- 内核中的中断驱动必须支持作业控制
- 必须提供对某些作业控制信号的支持
从shell使用作业控制功能角度观察,可以在前台或者后台启动一个作业。一个作业只是几个进程的集合,通常是一个进程管道。
vi main.c在前台启动了只有一个进程的一个作业。
pr *.c | lpr & make all & 在后台启动了两个作业。这两个后台作业所调用的进程都在后台运行。
正如前述,我们需要一个支持作业控制的shell及使用作业控制提供的功能。
当启动一个后台作业时,shell赋予它一个作业标识,并打印一个或几个进程id。
cat > tmp &
&表示进程放入后台 fg %1将1号作业放置到前台
& 最经常被用到 这个用在一个命令的最后,可以把这个命令放到后台执行
ctrl + z 可以将一个正在前台执行的命令放到后台,并且暂停
jobs 查看当前有多少在后台运行的命令
fg 将后台中的命令调至前台继续运行
如果后台中有多个命令,可以用 fg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)
bg 将一个在后台暂停的命令,变成继续执行
如果后台中有多个命令,可以用bg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)
我们可以键入一个影响前台作业的特殊字符--挂起键(一般用 ctrl-Z)与终端进程交互作用。键入次支付是终端驱动程序将信号SIGTSTP送至前台进程组的所有进程,后台进程组作业不受影响。实际上有三个特殊字符可以使终端驱动程序产生信号,并将它们送至前台进程组
- 中断字符(一般采用DELETE或CTRL-C)产生SIGNT
- 退出字符(一般采用Ctrl-\)产生SIGQUIT
- 挂起字符(一般采用Ctrl-Z)产生SIGTSTP
终端驱动程序必须处理与作业控制有关的另一种情况。我们可以有一个前台作业,若干个后台作业,这些作业中哪一个接受我们在终端上键入的字符呢?只有前台作业接收终端输入。如果后台试图读取终端,那么这并不是一个错误,但是终端驱动程序检测这种情况,并且发送一个特定的信号SIGTTIN给后台作业。这通常会停止此后台作业,而有关用户则会得到这种情况的通知,然后就可以将此作业转为前台作业运行,于是它就可读终端。
如果后台作业输出到终端控制又将发生什么呢?这是一个我们可以允许或禁止的选择项。通常可以用stty命令来改变这一选择项
stty tostop 命令可以禁止后台作业向控制终端输出
shell执行程序
进程并没有终端进程控制组。进程属于一个进程组,而进程组属于一个对话期。对话期可能有也可能没有控制终端。如果它确实有一个控制终端,则此终端设备知道其前台进程的进程组id。这一值可以用tcsettpgrp函数在终端驱动程序中设置。前台进程组id是宋段的一个属性而不是进程的属性。
孤儿进程组
一个父进程已终止的进程成为孤儿进程,这种进程由init进程收养。现在我们要说明整个进程组也可成为孤儿。