会话与终端
一.会话与终端
1.1会话
会话(session)是操作系统中用于管理进程的抽象概念,它提供了一个运行环境和资源共享的上下文。会话包含了一组相关的进程,这些进程具有共同的会话标识符(session ID)。
在一个会话中,通常有一个特殊的进程被指定为会话首领(session leader)。会话首领是该会话的控制进程,它通常是由用户启动的程序(如shell)。会话首领的进程ID(PID)就是该会话的ID。
一个会话可以包含多个进程组(process group),每个进程组由一组进程构成。进程组是为了方便集中管理和控制一组相关联的进程。进程组有一个唯一的进程组ID(PGID),最常见的情况是进程组ID与会话ID相同。
会话的概念提供了一些重要的功能和特性:
进程间通信:会话中的进程可以通过进程间通信(IPC)机制相互通信和共享信息。常见的IPC方式包括管道、命名管道、消息队列、共享内存和信号。
控制终端:会话通常与一个控制终端相关联,这个终端用于输入和输出的交互。控制终端通常是一台终端设备或一个伪终端(pty)。会话首领可以通过控制终端与用户进行交互,并控制终端的行为。
作业控制:会话概念提供了作业控制的机制,即可以将进程从前台切换到后台,或者从后台切换到前台。前台作业是当前正在与用户交互的作业,而后台作业是在后台运行而无需用户交互的作业。使用作业控制命令(如bg、fg、jobs)可以操作作业的状态和行为。
会话注销:会话概念也与用户会话登录和注销相关。当用户登录时,会话被创建;当用户注销或会话首领进程退出时,会话被销毁。
总的来说,会话是操作系统提供给进程的一个抽象层,用于管理进程组、提供运行环境和资源共享。会话的核心组成部分是会话首领和进程组,通过控制终端、进程间通信和作业控制等机制,提供了进程间的交互和协作,会话是用来管理进程组
。
1.2会话的诞生
setsid函数
调用setsid函数可以创建一个新的会话,并将调用者(应用程序)作为新会话的首进程。新会话的首进程会成为新会话的领导者(session leader),即会话首进程。
具体步骤如下:
- 应用程序调用setsid函数。setsid函数通常会在子进程中调用,以确保子进程成为新会话的首进程。
- 如果调用setsid的进程不是一个进程组的首进程,那么会创建一个新的会话,并将调用者设置为会话的首进程。这将使得调用者脱离其父进程和原会话,并成为一个新的会话领导者。
- 新会话不会与任何控制终端关联。这是因为新会话的首进程没有从父进程继承终端的能力,所以会话中的进程无法与终端交互。
- 如果调用者之前已经是一个进程组的首进程,则setsid调用失败,返回-1。
通过调用setsid函数,应用程序可以创建一个新的独立会话,该会话没有与任何终端相关联,可以在后台运行,并且拥有一些会话特有的属性和权限。这在服务器程序、守护进程或后台任务中非常有用。
打开终端
当用户在终端正确登录后,Linux系统会创建一个新的会话,并将Shell进程作为会话的首进程(也可以称为会话首领)。这个过程通常是由登录管理器(如getty或login)处理的。
下面是创建新会话的一般过程:
- 用户通过终端正确登录,登录管理器验证用户的身份。
- 验证成功后,登录管理器会调用系统的登录处理程序来启动Shell进程。
- 登录处理程序会调用setsid函数,以创建一个新的会话并使Shell进程成为会话首进程。
- 新的会话中的Shell进程继承了会话首进程的进程组ID(PGID),会话ID(SID)和控制终端(如果有)。
- 会话首进程(即Shell进程)会接管控制终端,并作为用户与终端交互的主要接口。
通过将Shell进程设置为新会话的首进程,可以使Shell获得一些与会话相关的特性:
- Shell进程可以接收和处理与控制终端相关的信号(如SIGHUP)。
- Shell进程可以管理会话中其他进程组的控制终端访问权限。
- Shell进程可以使用作业控制工具(如fg、bg、jobs)来管理会话中的进程组。
- Shell进程作为会话首进程,可以方便地切换前台和后台进程组。
这种创建新会话的方式使得Shell进程具有更大的控制权和灵活性,能够管理会话中的进程并与用户进行交互。
终端与会话
在Linux系统中,会话(session)和终端之间的关系是通过控制终端设备(controlling terminal)来建立的。控制终端是一个字符设备,它与终端设备(如TTY)或伪终端(PTY)相关联。
当用户在终端正确登录后,系统会为其创建一个新的会话,并将该终端设备作为该会话的控制终端。通过控制终端,用户可以与该会话进行交互。
具体的过程如下:
- 用户在终端正确登录后,登录管理器会为其分配一个控制终端设备,该设备会在登录过程中打开。
- 然后,登录管理器使用exec函数族中的一个函数(如execle或execlp)来启动Shell进程。
- Shell进程成为会话的首进程,并继承控制终端的文件描述符。
- 用户在终端输入的命令将通过控制终端设备传递给Shell进程进行处理,Shell进程的输出也将通过控制终端设备显示给用户。
需要注意的是,一个会话可以有一个控制终端,但一个控制终端可以控制多个会话。例如,在多个终端中登录多个用户会话时,每个会话都会有自己的控制终端设备。
综上所述,会话与终端之间的关系是通过控制终端设备建立的。控制终端设备允许用户在终端上与会话进行交互,用户输入的命令和会话的输出都通过控制终端设备进行传输。再次对之前的回答错误表示诚挚的道歉,并感谢您的指正。如还有任何问题,请随时告知。
前台进程组
当Shell进程启动时,默认情况下会成为前台进程组的首进程,并占用与该前台进程组关联的控制终端来运行。
当Shell启动其他应用程序时,这些应用程序并不会成为新会话的首进程。相反,它们仍然是Shell进程的子进程,并继承了Shell进程的会话ID(SID)、进程组ID(PGID)和控制终端。
控制终端只在前台进程组的首进程中被占用。当Shell进程启动其他应用程序时,这些应用程序仍属于同一前台进程组,并与Shell进程共享控制终端。它们可以通过控制终端进行输入输出交互。
需要注意的是,一旦Shell进程在前台启动了一个作业(例如运行一个长时间运行的命令),该作业将占用控制终端。在此期间,Shell进程将无法使用控制终端进行输入输出,直到作业运行结束或被挂起。
总结来说,Shell进程在启动时,默认是前台进程组的首进程,并会占用会话相关联的控制终端。而Shell进程启动的其他应用程序仍然是Shell进程的子进程,并共享同一控制终端。
后台进程组
在Shell进程中,可以使用"&"符号来指定一个程序在后台运行。当程序在后台运行时,它将成为一个后台进程,并不会占用终端。这意味着你可以在程序运行的同时,继续在Shell中输入命令和与终端进行交互。
具体启动一个后台进程的方法是,在Shell中输入程序的命令,命令的末尾加上"&"符号,示例:
$ program_name &
当程序在后台运行时,Shell进程会立即返回一个进程ID(PID),然后就可以继续接收和执行其他命令。
而当我们按下"Ctrl+Z"组合键时,会向当前前台进程发送一个SIGTSTP信号,导致该进程被挂起。此时,终端的控制权会返回给Shell进程,并且挂起的进程会变为后台中断的进程。
通过"Ctrl+Z"将进程挂起后,可以使用"bg"命令将其切换到后台继续运行,或者使用"fg"命令将其切换到前台恢复执行,jobs
查看后台进程组。
使用"bg"命令可以将挂起的进程设置为后台运行,示例:
$ bg %job_number
这里的"job_number"是挂起进程的作业号。
使用"fg"命令可以将挂起的进程设置为前台运行,示例:
$ fg %job_number
同样,"job_number"是挂起进程的作业号。
总结起来,后台进程中的程序不会占用终端。在Shell进程中启动一个程序时,可以通过在命令的末尾加上"&"符号来将其指定为后台进程。按下"Ctrl+Z"组合键会挂起当前的前台进程,并将控制权返回给Shell,使用"bg"命令可以将挂起的进程切换到后台运行,而使用"fg"命令则可以将其切换到前台继续执行。
- 点赞
- 收藏
- 关注作者
评论(0)