1、进程组
•
进程组是一个或多个进程的集合
•
#include <
unistd.h
>
•
pid_t
getpgrp
(void); #
获取进程组
ID
•
每个进程组有一个组长(其进程
ID=
进程组
ID
),组长进程终止时,进程组依然存在
•
一个进程可以加入一个现有的进程组,或创建一个新的进程组
•
int
setpgid
(
pid_t
pid
,
pid_t
pgid
);
•
一个进程只能设置自己的或其子进程的进程组
ID
2、会话
•
会话是一个或多个进程组的集合
•
#include <
unistd.h
>
•
pid_t
setsid
(void); #
创建新的会话
•
如果当前进程不是一个进程组长,将创建一个新的会话,结果:
•
1
、这个进程成为会话的领导,也是这个会话中的唯一进程
•
2
、这个进程成为新进程组的组长,进程组
ID
等于这个进程的进程
ID
•
3
、这个进程没有控制终端
3、控制终端
•
一个会话可以有一个控制终端,通常是我们登录的终端窗口
•
创建与控制终端连接的对话领导称为控制进程
•
对话内的进程组可以分为一个前台进程组及一个或多个后台进程组
•
终端产生的中断信号(
Ctrl+C
)或退出信号(
Ctrl+\
)只能送给前台进程组
•
终端检测到网络断连后,将给会话领导(也是控制进程)发送挂起信号
•
有时不管标准输入、标准输出是否被重新定向,程序都要与控制终端交互作用,保证程序读写控制终端的方法是打开文件
/
dev
/
tty
•
典型的例子是用于读口令的
getpass
(3)
函数
•
看这个例子,
salaries
文件包含工资信息,文件本身已加密
•
crypt < salaries |
lpr
4、任务控制
•
任务控制允许在一个终端上同时运行多个任务,可以控制哪个任务在前台运行,哪些任务在后台运行
•
所谓任务,其实就是一组进程
•
在终端启动进程时,可以指定前台或后台运行,如:
•
vi
main.c
#
启动一个前台任务
•
pr
*.c |
lpr
& #
启动一个后台任务
•
make all & #
启动后台任务
•
后台任务读取输入时的交互示例:
$ cat > temp.foo & start in background, but it'll read from standard input
[1] 1681
$ we press RETURN
[1] + Stopped (SIGTTIN) cat > temp.foo &
$ fg %1 bring job number 1 into the foreground
cat > temp.foo the shell tells us which job is now in the foreground
hello, world enter one line
^D type the end-of-file character
$ cat temp.foo check that the one line was put into the file
hello, world
5、SHELL执行程序
•
查看
shell
如何执行程序,以及与进程组、控制终端和会话等概念的关系
•
ps
-o
pid,ppid,pgrp,session,tpgid,comm
# Linux
平台精确支持
•
显示结果取决于
shell
是否支持任务控制(假定支持任务控制)
•
PID PPID PGRP SESS TPGID COMMAND
•
2837 2818 2837 2837 5796 bash
•
5796 2837 5796 2837 5796
ps
•
ps
-o
pid,ppid,pgrp,session,tpgid,comm
&
•
PID PPID PGRP SESS TPGID COMMAND
•
2837 2818 2837 2837 2837 bash
•
5797 2837 5797 2837 2837
ps