待填坑
待填坑
- 进程组是一个或多个进程的集合,通常是在同一个作业中结合起来的。
- 每个进程除了有一个进程ID之外,还属于一个进程组。
- 同一进程组中的各进程接收来自同一终端的各种信号。
- 每个进程组有一个唯一的ID:进程组ID。
#include <unistd.h>
pid_t getpgrp(void);
功能:返回调用进程的进程组ID。
pid_t getpgid(pid_t pid);
返回值:返回进程pid的进程组ID。出错返回-1。
注:getpgid(0) 等同于 getpgrp()。
- 每个进程组有一个组长进程,组长进程的进程组ID等于其PID。
- 组长进程可以创建进程组、创建该组中的进程,然后终止。
- 进程组的存在,与组长进程是否终止无关。只要进程组中有一个进程存在,该进程组就存在。
- 进程组的生命期:从进程组创建开始,到其中最后一个进程离开为止。
- 进程组的最后一个进程可以终止,也可以转移到另外一个进程组。
#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);
返回值:成功返回0,出错返回-1。
功能:加入一个现有的进程组,或者创建一个进程组。
形参说明:
将pid进程的进程组ID设置为pgid。
pid == pgid : pid指定的进程变成进程组组长。
pid == 0 : 使用调用者的 pid。
pgid == 0 : 由pid指定的进程ID用作进程组ID。
注:
1 一个进程只能为自己或自己的子进程设置进程组ID
2 子进程调用了exec后,父进程不能更改子进程的进程组ID。
- waitpid 函数可被用来等待指定进程组中的一个进程终止。
会话,session,是一个或多个进程组
的集合。
#include <unistd.h>
pid_t setsid(void);
返回值:成功返回进程组ID;若出错返回-1。
功能:如果调用此函数的进程不是进程组组长,则创建一个新会话。
如果调用进程是进程组组长,则返回出错。
创建新会话的动作:
- 调用进程变成新会话的会话首进程。该进程是会话中的唯一进程。
- 调用进程成为一个新进程组的组长,pgid = pid。
- 该进程没有控制终端,如果调用之前有,也会被切断联系。
技巧:防止调用出错,通常调用fork,父进程结束,子进程继续。
#include <unistd.h>
pid_t getsid(pid_t pid);
返回值:成功,返回会话首进程的进程组ID;出错返回-1。
功能:返回会话首进程的进程组ID。
形参说明:
pid == 0: 返回调用进程的会话首进程的进程组ID。
pid 不属于调用者所在的会话,将会返回出错。(某些实现)
会话和进程组的一些特性:
- 一个会话可以有一个控制终端。通常是终端设备或伪终端设备。
- 建立与控制终端连接的
会话首进程
被称为控制进程
。 - 一个会话中的进程组,可被分为一个前台进程组,一个或多个后台进程组。
- 如果一个会话有一个控制终端,则它有一个前台进程组,其余为后台进程组。
- 在终端键入的任何输入,以及中断信号、退出信号,都会被发送到前台进程组。
- 终端的挂断信号,会被发送到控制进程。
保证程序能与控制终端对话的方法是open文件 /dev/tty 。
关于getpass,终端回显被关闭的部分,没看懂。
#include <unistd.h>
pid_t tcgetpgrp(int fd);
返回值:返回前台进程组ID。若出错,返回-1。
int tcsetpgrp(int fd, pid_t pgrpid);
返回值:成功返回0,出错返回-1。
功能:将前台进程组ID设置为pgrpid。
形参说明:
fd:该会话的控制终端。
pgrpid:前台进程组ID。
#include <termios.h>
pid_t tcgetsid(int fd);
功能:返回会话首进程的进程组ID;出错返回-1。
形参fd:控制TTY的文件描述符。
作业,即进程组。作业控制允许在一个终端上启动多个作业,控制哪一个作业可以访问终端,以及哪一些作业在后台运行。
支持作业控制的条件:
- 支持作业控制的shell
- 内核中的终端驱动程序必须支持作业控制
- 内核必须提供对某些作业控制信号的支持
从用户的角度看作业控制:用户可以在前台或后台启动一个作业。
- 在后台启动作业,只需在命令的结尾加上
&
。 - 启动后台作业时,shell会返回一个作业标识符,并打印一个或多个进程ID。
- 使用命令
fg %作业编号
可将作业从后台切换到前台。 - 当后台作业完成并键入回车时,shell通知作业已经完成。
- 有3个特殊字符可使终端产生信号,并发送至前台进程组:
- 中断字符产生SIGINT,一般是Delete或Ctrl+C
- 退出字符产生SIGQUIT,一般是Ctrl+\
- 挂起字符产生SIGTSTP,一般是Ctrl+Z
终端IO与前后台作业:
- 只有前台作业接收终端输入。
- 后台作业尝试读取终端,会收到信号SIGTTIN,并且shell会通知用户。
- 只有前台进程可以输出到终端。
- 后台进程尝试输出到终端,会收到信号SIGTTOU,并且shell会通知用户。
用户收到通知后,可用命令fg,将作业转为前台。
shell是如何执行程序的,以及这与进程组、控制终端和会话等概念的关系。
暂时没看太懂,待填坑。
待填坑
待填坑