知识屋:更实用的电脑技术知识网站
所在位置:首页 > 操作系统 > linux

Linux/UNIX进程关系

发布时间:2014-09-05 17:41:06作者:知识屋

进程关系

进程组

每个进程除了有一个进程ID之外,还属于一个进程组。进程组是一个或多个进程的集合。通常他们与同一作业相关联,可接受来自同一终端的各种信号。

#include<unistd.h>

pid_tgetpgrp(void); /* POSIX.1version */

pid_t getpgid(pid_tpid);

intsetpgid(pid_t pid, pid_t pgid);

函数getpgrp返回调用进程的进程组ID。

getpid函数也有此功能。

进程可以通过调用setpgid来加入一个现有的组或创建一个新进程组。

会话

会话是一个或多个进程组的集合。

通常是由shell的管道将几个进程编成一组的。如下所示:

proc1 | proc2 &

proc3 | proc4 | proc5

其会话安排如下:

进程调用setsid函数建立一个新会话。

#include <unistd.h>

pid_t setsid(void);

还可调用getsid来返回会话首进程的进程组ID

#include <unistd.h>

pid_t getsid(pid_t pid);

控制终端

登录时,将自动创建控制终端。

程序与控制终端交互时,为保证程序能读写控制终端的方法是打开文件/dev/tty。在内核中,词特殊文件是控制终端的同义语。如果程序没有控制终端,则打开此设备将失败。

1. 一个会话可以有一个控制终端

2. 建立与控制终端联结的会话收进程被称为控制进程

3. 一个会话中的几个进程组可被分成一个前台进程组以及一个或几个后台进程组

4. 如果一个会话有一个控制终端,则它有一个前台进程,会话中的其他进程组则为后台进程组

5. 无论何时键入终端的中断键,就会将中断信号发送给前台进程组的所有进程

6. 无论何时键入终端的退出键,就会将退出信号发送给前台进程组的所有进程

7. 如果终端接口检测到的调制解调器已经断开网络,则将挂断信号发送给控进程。

tcgetpgrp、tcsetpgrp和tcgetsid函数

#include <unistd.h>

pid_t tcgetpgrp(int fd);

int tcsetpgrp(int fd, pid_t pgrp);

tcgetpgrp函数返回调用前台进程的进程组ID,该前台进程组与在fd上打开的终端相关联。

如果进程有一个控制终端,则该进程可以调用tcsetpgrp将前台进程组ID设为pgrp,fd必须引用该会话的控制终端。

#include<termios.h>

pid_ttcgetsid(int fd);

该函数识别出控制终端的会话首进程的会话ID。

作业控制

作业控制允许在一个终端上启动多个作业(进程组),他控制哪个作业可以访问终端,以及那些作业也在后台运行。

catchen123@ubuntu:~$ cat > temp.foo & 在后台启动,但将从标准输入读

[1] 3894

chen123@ubuntu:~$

键入回车

[1]+ Stopped cat > temp.foo

chen123@ubuntu:~$fg %1 使1号作业成为前台作业

cat >temp.foo shell告诉我们现在哪一个作业在前台

hello,world 输入1行,后面接文件结束符(ctrl+D)

chen123@ubuntu:~$cat temp.foo 检查该行已送入文件

hello,world

chen123@ubuntu:~$

shell在后台启动cat进程,但是当cat视图读其标准输入时,终端驱动程序知道他是个后台作业,于是将SIGTTIN信号送至该后台作业。shell检测到其子进程的状态改变,并通知我们该作业已被停止。然后,我们用shell的fg 将此停止的作业送入前台运行。这样做可以使shell将此作业置入前台进程组,并将继续信号送给进程组。因为该作业现在位于前台进程组中,所以它可以读控制终端。

chen123@ubuntu:~$ cat temp.foo & 在后台执行

[1] 4125

chen123@ubuntu:~$hello,world

[1]+ Done cat temp.foo

chen123@ubuntu:~$stty tostop

chen123@ubuntu:~$cat temp.foo &

[1] 4129

chen123@ubuntu:~$

键入回车,发现作业已经停止

[1]+ Stopped cat temp.foo

chen123@ubuntu:~$ fg %1 在前台恢复停止的作业

cat temp.foo shell告诉我们现在哪一个作业在前台

hello,world 这是改作业的输出

总结:在shell命令后面加&,表示该命令将在后台启动。fg命令可以将后台作为送至前台。stty tostop可以禁止后台作业输出到终端。

shell执行程序

shell是如何执行程序、以及这与进程组、控制终端和会话等概念的关系.

shell将前台进程进程放在它自己的进程组中,shell则留在他自己的进程组中。
ps -o pid,ppid,pgrp,session,tpgid,comm

PID PPID PGRP SESS TPGID COMMAND

4302 4293 4302 4302 4359 bash

4359 4302 4359 4302 4359 ps

shell将前台作业(ps)放入它自己的进程组(4359)中。ps命令是组长进程,并是该进程组中唯一的进程。进一步讲,此进程组具有控制终端,所以它是前台进程组。我们的登录shell在执行ps命令时是后台进程。但需要注意的是,这两个进程组4302和43509都是同一会话的成员。

在后台执行此进程:

ps -o pid,ppid,pgrp,session,tpgid,comm &

PID PPID PGRP SESS TPGID COMMAND

4302 4293 4302 4302 4302 bash

4390 4302 4390 4302 4302 ps

再一次,ps命令被放入自己的进程组中,但是此时进程组(4302)不再是前台进程组,而是一个后台进程组。登录的shell是前台进程组。

按下列方式在一个管道中执行两个进程:

ps -opid,ppid,pgrp,session,tpgid,comm | cat

PID PPID PGRP SESS TPGID COMMAND

4302 4293 4302 4302 4411 bash

4411 4302 4411 4302 4411 ps

4412 4302 4411 4302 4411 cat

两个进程ps和cat1都在一个新进程组中(4411),这是一个前台进程。shell创建将执行管道线中的进程,也就是说ps和cat的父进程都是shell。

当在后台执行此管道线时,其结果类似。

ps -opid,ppid,pgrp,session,tpgid,comm | cat &

PID PPID PGRP SESS TPGID COMMAND

4302 4293 4302 4302 4302 bash

4440 4302 4440 4302 4302 ps

4441 4302 4440 4302 4302 cat

这里需要注意,使用不同的shell,那么它创建的各个进程的顺序是不相同的。以上讨论都是基于Linux上具有作业控制的shell为例。

如果linux上没有作用控制的shell,那么管道线中最后一个进程是shell的子进程,而执行管道中其他命令的进程则是该最后一个进程的子进程。

孤儿进程组

一个其父进程已终止的进程称为孤儿进程,这种进程由init进程收养。整个进程组也可以称为孤儿。

孤儿进程组的定义:一个进程组不是孤儿进程组的条件是,该组中每个成员的父进程要么是该组的一个成员,要么不是改组所属会话的成员。

(免责声明:文章内容如涉及作品内容、版权和其它问题,请及时与我们联系,我们将在第一时间删除内容,文章内容仅供参考)
收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜