Linux session (session)

The author previous text " Linux job control " introduces the concept of process groups (job) as well as common job control operation, the paper then introduces the concept of the session. This article demonstrates the use of part of the environment is ubuntu 18.04.

What session that?

The most common Linux session generally refers to the shell session. Shell session is the current state of the terminal, the terminal can have only one session. When we open a new terminal, will always create a new shell session.

The relationship between processes is, session by a group consisting of one or more processes. In general, all processes from a single login belong to the same session. We can understand the relationship between processes, process group and session by the following figure:

A session is created by the first session of a process, under normal circumstances is a shell process is created when you open a terminal. This process is also called the process leading the session. PID Session of the process that is leading the SID session. We can see the SID by the following command:

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

Session Each process group is called a job, a job will be the session foreground job (foreground), the other job is a background job (background). Each session connecting a control terminal (control terminal), a control input terminal is sent to the reception job, the output job generated from the front are also sent to the control terminal. While the signal generated by the control terminal, such as ctrl + z, etc. are transmitted to the reception job.

In general session and the terminal is one to one relationship, when we open multiple terminal window, actually created multiple session.

Meaning that a plurality of Session Work (Job) running in a terminal, one of which is the Job foreground, which directly receives the input terminal and outputs the result to the terminal. Other job is running in the background.

session of the birth and demise

Typically, a new session is created by the system login program, leading the process of the session is to run the user's login shell process. Each process will belong to a newly created process group, when creating a process, and it is the parent process with a process group, session in.

The only way the process into a different session is to use setsid function to become the leading process of a new session. This session will also lead the process into a new process group.

When all processes are in session ended session also disappeared. The actual use of such a network is disconnected, session sure to extinction. The other is the normal demise, such as making the process leading session exit. In general session of the lead process is the shell process, if it is in the foreground, we can use the exit command or ctrl + d let it exit. Or we can kill the process session lead directly through the kill command. Inside this principle is: when the system detects a hang up (HANGUP) condition, the kernel sends a SIGHUP signal to drive the entire session. Typically, this will kill all processes in session.

Relations with the terminal session
if the session is associated pseudo-terminal, this pseudo terminal itself with the establishment of the session created, the end of the session, then the pseudo terminal will be destroyed.
If the session is associated tty1-6, tty will not be destroyed. Since the terminal device is created in the system initialization time, it is not dependent on the establishment of the session, so when the session exits, tty still exists. Just init system after the end of the session, restarts getty to listen to this 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 信号,但是否允许写入的控制会更加的复杂。

参考:
What is the definition of a “session” in linux?
Linux session和进程组概述
Job Control
Linux TTY/PTS概述
setsid source code

Guess you like

Origin www.cnblogs.com/sparkdev/p/12146305.html