终端和进程关系
bash和终端
1 | ps -ef | grep bash |
pts(虚拟终端),每连接一个虚拟终端到ubantu操作系统就会新出现一个bash进程(shell【壳】),bash运行起来就是那个黑窗口,bash用来解释用户输入的各个命令比如ls,ps等
bash=shell=命令解释器,,,bash是一个可执行文件
用xshell创建一个新连接后可以观察到多了一个bash进程
bash是一个可执行文件,每打开一个终端就会多出一个bash进程。
终端和进程
进程组和会话
每个进程还属于一个进程组:一个或者多个进程的集合,每个进程组有一个唯一的进程组ID,可以调用系统 函数来创建进程组、加入进程组
“会话”(session):是一个或者多个进程组的集合.
一般,只要不进行特殊的系统函数调用,一个bash(shell)上边运行的所有程序都属于一个会话,而这个会话有一个session leader;
那么这个bash(shell)通常就是session leader; 你可以调用系统功函数创建新的session。
ps -eo
a)如果我 xshell终端要断开的话,系统就会发送SIGHUP信号(终端断开信号),给session leader,也就是这个bash进程
b)bash进程 收到 SIGHUP信号后,bash会把这个信号发送给session里边的所有进程,收到这个SIGHUP信号的进程的缺省动作就是退出;
strace跟踪
关闭运行nginx的终端后bash如图所示,
如下图所示,kill(-5871, SIGHUP) :发送信号SIGHUP给这个 -5871的绝对值(nginx进程ID)所在的进程组;所以nginx进程就收到了SIGHUP信号
综合来讲,这个bash先发送SIGHUP给同一个session里边的所有进程;
然后再发送SIGHUP给自己;
孤儿进程
父进程运行结束,但子进程还在运行(未运行结束)的子进程就称为孤儿进程(Orphan Process)。孤儿进程最终会被 init 进程(进程号为 1 )所收养,并由 init 进程对它们完成状态收集工作。
孤儿进程是没有父进程的进程,为避免孤儿进程退出时无法释放所占用的资源而变为僵尸进程,进程号为 1 的 init 进程将会接受这些孤儿进程,这一过程也被称为“收养”。init 进程就好像是一个孤儿院,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤 儿进程的父进程设置为 init ,而 init 进程会循环地 wait() 它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init 进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。
终端关闭不退出进程
方法一:代码里设置忽略对应signal的逻辑
1 |
|
直接关闭运行nginx的那个终端之后,ngnix变成了孤儿进程。
方法二:代码里借助setsid函数并借助子进程
1 |
|
方法三:命令行使用setsid
1 | setsid ./nginx |
方法四:命令行使用nohup
1 | nohup ./nginx |
nohup(no hang up不要挂断),用该命令启动的进程跟上边忽略掉SIGHUP信号,道理相同。该命令会把屏幕输出重新定位到当前目录的nohup.out而不是直接打印到终端
后台运行
1 | ./nginx & |
后台运行当前程序,可以输入命令并且解释运行但是ctrl+’c’无法停止当前程序,只能等程序运行完成。fg切换到前台后才可以用ctrl+’c’停止当前程序。