进程
进程组(process group)
每个进程组都有一个leader进程称为进程组组长,进程组组长的pid与进程组pgid一致
会话(session)
会话是若干进程组的集合
一个会话最多拥有一个控制终端(tty或pts)
一个会话有且只有一个前台进程组,可以有若干后台进程组
会话的控制终端被前台进程组的所有进程共享
每个会话有一个会话首进程,该进程的pid与sid一致
当会话首进程退出时,会给该会话的所有进程发送sighup信号(kill -1 pid)
当我们使用ssh登录到一台主机时,其实就开启了一个bash进程,可以通过以下命令查看该bash进程的pid
创建bash进程的同时也为它创建一个会话以及一个控制终端,我们登录到主机时能够输入命令的那个就是控制终端。通过以下的命令查看会话id与终端名称等信息:
解释一下上面的前几列:
PPID:父进程id
PID:进程id
PGID:进程组id
SID:会话id
TTY:控制终端名称
TPGID:该session的前台进程组id
可以看出:pid等于pgid,所以bash进程是进程组29575的组长;pid等于sid,所以bash进程是会话29575的会话首进程。
接下来,我们在当前终端下起一个进程,先编写脚本 a.sh
,内容如下:
执行命令:
接下来,我们在另一个终端(另一个ssh登录)下查看该session下的进程:
可以看到,这几个进程共用一个控制终端(pts/2)。在这里要注意的是,a.sh在执行命令sleep 1000
时,是起了一个新的进程,a.sh进程之所以没有退出是要等待sleep 1000
进程结束返回。这几个进程的父子关系是:
接下来,我们在新的终端下终止会话首进程bash进程:
执行该命令后,29575的bash进程的连接就断开了。我们查看会话29575中的进程情况:
发现,a.sh进程与sleep进程不在了,但dockerd进程还在。我猜测是:会话首进程给进程组中的每个进程发送了sighup信号,a.sh
进程与sleep 1000
进程接收到信号后终端运行退出,而dockerd进程却忽略了该信号还继续执行。
这里我们可以手动给dockerd进程发送sighup信号,验证该进程会忽略该信号。执行以下命令,发现dockerd进程还在:
同时,dockerd进程的tty变成了?
,说明该进程已经没有了终端输入与输出能力;dockerd的父进程id变成1,说明该进程已被init进程管理;sid与pgid却还保持没变。
nohup
vs &
nohup
vs &
后台命令符号&
的意思是,子进程进入后台执行模式,父进程不需要等待子进程的返回就可以继续往后面执行。
nohup的意思是,当进程接收到sighup信号时,选择忽略,不会主动结束执行。
Reference
[1] https://www.ibm.com/developerworks/cn/linux/1702_zhangym_demo/index.html [2] https://blog.csdn.net/outofmemo/article/details/54151326
Last updated