笔者在前文《Linux job control》中介绍了进程组(job)的概念以及常见的 job control 操作,本文接着介绍 session 的概念。本文中演示部分使用的环境为 ubuntu 18.04。

session 是什么?

我们常见的 Linux session 一般是指 shell session。Shell session 是终端中当前的状态,在终端中只能有一个 session。当我们打开一个新的终端时,总会创建一个新的 shell session。

就进程间的关系来说,session 由一个或多个进程组组成。一般情况下,来自单个登录的所有进程都属于同一个 session。我们可以通过下图来理解进程、进程组和 session 之间的关系:

会话是由会话中的第一个进程创建的,一般情况下是打开终端时创建的 shell 进程。该进程也叫 session 的领头进程。Session 中领头进程的 PID 也就是 session 的 SID。我们可以通过下面的命令查看 SID:

$ ps -o pid,ppid,pgid,sid,tty,comm

Session 中的每个进程组被称为一个 job,有一个 job 会成为 session 的前台 job(foreground),其它的 job 则是后台 job(background)。每个 session 连接一个控制终端(control terminal),控制终端中的输入被发送给前台 job,从前台 job 产生的输出也被发送到控制终端上。同时由控制终端产生的信号,比如 ctrl + z 等都会传递给前台 job。

一般情况下 session 和终端是一对一的关系,当我们打开多个终端窗口时,实际上就创建了多个 session。

Session 的意义在于多个工作(job)在一个终端中运行,其中的一个为前台 job,它直接接收该终端的输入并把结果输出到该终端。其它的 job 则在后台运行。

session 的诞生与消亡

通常,新的 session 由系统登录程序创建,session 中的领头进程是运行用户登录 shell 的进程。新创建的每个进程都会属于一个进程组,当创建一个进程时,它和父进程在同一个进程组、session 中。

将进程放入不同 session 的惟一方法是使用 setsid 函数使其成为新 session 的领头进程。这还会将 session 领头进程放入一个新的进程组中。

当 session 中的所有进程都结束时 session 也就消亡了。实际使用中比如网络断开了,session 肯定是要消亡的。另外就是正常的消亡,比如让 session 的领头进程退出。一般情况下 session 的领头进程是 shell 进程,如果它处于前台,我们可以使用 exit 命令或者是 ctrl + d 让它退出。或者我们可以直接通过 kill 命令杀死 session 的领头进程。这里面的原理是:当系统检测到挂断(hangup)条件时,内核中的驱动会将 SIGHUP 信号发送到整个 session。通常情况下,这会杀死 session 中的所有进程。

session 与终端的关系

如果 session 关联的是伪终端,这个伪终端本身就是随着 session 的建立而创建的,session 结束,那么这个伪终端也会被销毁。

如果 session 关联的是 tty1-6,tty 则不会被销毁。因为该终端设备是在系统初始化的时候创建的,并不是依赖该会话建立的,所以当 session 退出,tty 仍然存在。只是 init 系统在 session 结束后,会重启 getty 来监听这个 tty。

nohup

如果我们在 session 中执行了 nohup 等类似的命令,当 session 消亡时,相关的进程并不会随着 session 结束,原因是这些进程不再受 SIGHUP 信号的影响。比如我们执行下面的命令:

$ nohup sleep 1000 >/dev/null 2>&1 &

此时 sleep 进程的 sid 和其它进程是相同的,还可以通过 pstree 命令看到进程间的父子关系:

如果我们退出当前 session 的领头进程(bash),sleep 进程并不会退出,这样我们就可以放心的等待该进程运行结果了。

nohup 并不改变进程的 sid,同时也说明在这种情况中,虽然 session 的领头进程退出了,但是 session 依然没有被销毁(至少 sid 还在被引用)。重新建立连接,通过下面的命令查看 sleep 进程的信息,发现进程的 sid 依然是 7837:

但是此时的 sleep 已经被系统的 1 号进程 systemd 收养了:

setsid

setsid 会创建一个新的 session,它的目的是让进程在后台执行命令,实现方式就是让命令进程运行在一个新的与终端脱离的 session 中。看下面的示例:

$ setsid sleep 1000

查找之下居然没有发现 sleep 进程的踪迹:

通过 grep 查询 sleep 进程的 PID:

去查看 sleep 进程所在的 sid,发现是一个新的 session ID,并且没有关联终端:

当一个进程通过调用 setsid 成为一个新的 session 领头进程时,它会与控制终端断开连接。

此时通过 pstree 查看进程间的关系,发现 sleep 进程直接被系统的 1 号进程 systemd 收养了:

控制终端(controlling terminal)

控制终端是进程的一个属性。通过 fork 系统调用创建的子进程会从父进程那里继承控制终端。这样,session 中的所有进程都从 session 领头进程那里继承控制终端。Session 的领头进程称为终端的控制进程(controlling process)。简单点说就是:一个 session 只能与一个终端关联,这个终端被称为 session 的控制终端(controlling terminal)。同时只能由 session 的领头进程来建立或者改变终端与 session 的联系。我们可以通过 ps 命令查看进程的控制终端:

支持 job control 的 shell 必须能够控制在某一时刻由哪个 job 使用终端。否则,可能会有多个 job 试图同时从终端读取数据,这会导致进程在接收用户输入时的混乱。为了防止这种情况发生,shell 必须按照预定的协议与终端驱动程序协作。

shell 一次只允许一个 job(进程组)访问控制终端。来自控制终端的某些输入会导致信号被发送到与控制终端关联的 job(进程组)中的所有进程。该 job 被称为控制终端上的前台 job。由 shell 管理的其他 job 在不访问终端的情况下,被称为后台 job。

Shell 的职责是通知 job 何时停止何时启动,还要把 job 的信息通知给用户,并提供机制允许用户继续暂停的 job、在前台和后台之间切换 job。比如前台 job 可以无限制的自由使用控制终端,而后台 job 则不可以。当后台 job 中的进程试图从其控制终端读取数据时,通常会向进程组发送 SIGTTIN 信号。这通常会导致该组中的所有进程停止(变成 stopped 状态)。类似地,当后台 job 中的进程试图写入其控制终端时,默认行为是向进程组发送 SIGTTOU 信号,但是否允许写入的控制会更加的复杂。

linux session存储目录,Linux session(会话)相关推荐

  1. linux 如何赋值目录,Linux文件系统之目录的建立

    一:前言 在用户空间中,建立目录所用的API为mkdir().它在内核中的系统调用入口是sys_mkdir().今天跟踪一下 函数来分析linux文件系统中目录的建立过程. 二:sys_mkdir() ...

  2. linux php 上级目录,Linux目录架构详解_php

    linux和Windows操作系统的显著区别之一就是目录架构的不同.Linux操作系统的目录架构遵循文件系统层级结构标准.不知你是否使用ls命令浏览过Linux的根目录"/",亲爱 ...

  3. linux文件存储结构,Linux文件存储方式以及软硬链接

    在Linux中,文件包括常规文件.目录.符号链接等.为了方便理解,在本文中,文件指常规文件,目录指常规目录. 文件 1. 文件是如何存储的? 文件是由3部分组成 的: 文件名: dentry 文件元数 ...

  4. Linux ln -s目录,Linux 中的 ln 命令

    Linux ln 命令 Intro Linux 中的文件分为 Hard Link 和 Symbolic Link 两种.Hard Link 文件又被称为硬链接文件.实体链接文件,Symbolic Li ...

  5. linux 锁定用户目录,Linux vfpd锁定用户目录

    在linux ftp配置中,为了防止用户cd 到其他目录,需要锁定用户的根目录. Step1:修改配置文件 [root@ess ~]# vi /etc/vsftpd/vsftpd.conf #chro ...

  6. linux++tar打包目录,linux中tar命令打包目录与排除目录打包linux操作系统 -电脑资料...

    本文章来给各位朋友详细介绍关于linux中tar命令打包目录与排除目录打包有需要了解tar命令的使用方法的朋友可进行参考参考, 打包压缩目录很简单如下代码如下复制代码 tar -czf small.t ...

  7. linux挂载wondiws目录,linux cifs自动挂载windows硬盘或文件夹

    1.在要挂载的windows系统中找到需要挂载的硬盘或者文件夹,把它设置为共享 例如:在D盘下建立文件夹shared,设为共享 2.在linux系统/mnt目录下创建一个文件夹 #mkdir /mnt ...

  8. linux weblogic启动目录,Linux下WebLogic开机启动设置

    为了方便管理,可以写一个启动脚本用来启动 weblogic,方法如下:用root用户登录Linux,打开目录/etc/rc.d/init.d,新建一个空文本文件,名称改为weblogic (此文件名为 ...

  9. linux的run目录,Linux 中run 目录详细介绍

    原标题:Linux 中run 目录详细介绍 /run 是各种各样数据的家园.例如,如果你查看 /run/user,你会注意到一组带有数字名称的目录. $ ls /run/user 1000 1002 ...

  10. linux 网卡配置目录,Linux目录结构以及网卡配置

    一.Linux下的目录结构 /bin 存放二进制命令 /boot系统引导程序 /dev设备,硬盘 /etc系统应用的配置文件 /home普通用户家目录 /lib库文件 /lib64 64位的库文件 / ...

最新文章

  1. OSI参考模型和网络编程
  2. 抢人饭碗了!推荐一款全自动的机器学习建模神器PyCaret
  3. 主成分分析法(PCA)原理漫谈
  4. 运放搭建主动滤波电路
  5. Java多线程实现异步调用
  6. Spring MVC源码分析(一) 说明
  7. cesium 经纬度绘制点_Cesium经纬度与坐标的问题
  8. Flutter高级第6篇:事件广播 、事件监听
  9. 项目开发文档编写规范【附文档模板】
  10. 40岁开始学习Android开发的我成了一名技术主管
  11. 申请并部署阿里云SSL免费证书详细流程
  12. 开涛的博客—公众号:kaitao-1234567,一如既往的干货分享
  13. IPSC和IPSC衍生细胞
  14. oracle用户删除了可以恢复吗,oracle_oracle误删数据恢复方法小结,如果用户误删/更新了数据后, - phpStudy...
  15. python创建目录(文件夹)
  16. 前端生成gif动态图下载
  17. Computer vision for solid waste sorting: A critical review of academic research 机器视觉垃圾分选综述翻译
  18. EXCELt添加单引号
  19. 二十五个深度学习相关公开数据集
  20. matlab 0106,MATLAB控制系统仿真与实例详解.pdf

热门文章

  1. js 正则清除html格式
  2. 如何做好项目的需求与业务调研?
  3. Ubuntu下mysql修改字符集为utf8
  4. mysql优化--避免数据类型的隐式转换
  5. tomcat启动超时(timeout)解决方法
  6. 粤港澳湾区邮轮产业崛起 构建邮轮母港群尚需加强合作
  7. [Vue CLI 3] 配置 webpack-bundle-analyzer 插件
  8. 每日一门之for循环的执行顺序
  9. 我爱刷题系列汇总(51-100)【2017.11.24-2018.01.12】
  10. P2341 [HAOI2006]受欢迎的牛