关于session和shell:常见的session一般是shellsession,终端中只有一个session,当我们打开一个新的终端时,总会创建一个新的session,session由一个或多个进程组组成。一般认为shell进程是会话的leader进程。lead进程的PID作为seeesion的SID。会话中的每个进程组称为一个作业。关于job(任务):执行一条命令会创建一个或多个进程。这些进程属于一个进程组。每个过程组都有一个组长。组长的pid就是进程组的id。可以通过ps命令查看进程进程组id:ps-opgid。通过管道连接的进程属于同一个进程组,子进程继承父进程的进程组和SID。(我们知道命令进程是由shell进程fork产生的子进程执行的,那么一个session中是否只有一个进程组?)(答:shell进程fork产生的子进程本来和shell组和控制终端,但是shell调用setpgid函数指定job中的一个子进程作为新进程组的groupleader,然后调用setpgid将该job中的其他子进程转移到这个进程组中。进程组如果需要在前台运行,调用tcsetpgrp函数设置为前台进程组,由于一个session只能有一个前台进程组,shell所在的进程组会自动成为后台进程group.)一个session只能有一个Foregroundjob,其余都是backgroundjobs,每个session连接一个控制终端(controlterminal)。控制端的输入会发送给前台作业,前台作业的标准输出也会发送给控制端,控制端产生的信号也会发送给前台作业。将进程放入不同会话的唯一方法是:setsid使其成为新会话的领导进程,该进程将被放入新的进程组。关于控制终端(controlterminal):控制终端是进程的一个属性,子进程会从父进程继承控制终端,所以一个会话中的所有进程都会从主进程继承控制终端属性。将多个进程放到一个进程组中的主要目的是为了方便管理,同时向同一个进程组发送信号。关于kill:kill命令默认向进程发送SIGTERM信号,但是可以设置SIGTERM信号被进程忽略,这样就无法关闭这些进程。这时使用kill-SIGKILL(kill-9)PID发送SIGKILL命令。这个信号不容忽视。关于session死亡:当session中的所有进程退出时,session就会死亡。正常死亡进程:内核发现终端关闭,向会话领导进程发送SIGHUP信号。会话领导进程接收到SIGHUP信号并将该信号发送给会话。对于中的每个进程,SIGHUP信号的默认处理方式是结束进程。内核发现终端被关闭:可能是远程登录时网络断开,或者终端窗口被X手动掉线。关于守护进程:守护进程是一个独立于控制终端的后台进程,并且无法通过控制终端与用户进行交互。守护进程是一个长时间运行的进程,例如服务器程序。通过调用setsid函数使一个进程成为守护进程(创建一个新的会话,放弃终端,创建一个新的进程组)。关于setsid函数:调用setstd函数会创建一个新的session,进程会成为session的leader进程,进程会创建一个新的进程组,有自己的PID。调用该函数的进程不允许是某个session的leader进程。(通过fork避免这个问题)setsid会放弃当前的控制终端。ps-x参数可以显示所有与终端无关的进程-a显示所有与终端相关的进程-u根据用户整理进程信息显示参考文章:https://my.oschina.net/moooof...https://www.cnblogs.com/spark...https://www.jb51.net/article/...
