- Linux使用和管理指南:从云原生到可观测性
- (奥)迈克尔·豪森布拉斯
- 1041字
- 2024-07-25 15:55:51
2.3.1 进程管理
内核中有许多与进程管理相关的部分。其中一些处理特定于CPU架构的事情(比如中断),而另一些则专注于程序的启动和调度。
在我们了解Linux细节之前,我们要注意,进程通常是基于可执行程序(或二进制文件)的面向用户的单元。另外,线程是进程上下文中的执行单元。你可能遇到过术语“多线程”,这意味着一个进程有许多并行执行,可能运行在不同的CPU上。
有了这个一般的观点,让我们看看Linux是如何做到的。从最细粒度到最小单元,Linux有以下内容:
会话
包含一个或多个进程组,并表示带有可选tty附加的面向用户的高级单元。内核通过一个称为会话ID(SID)的数字来标识会话。
进程组
包含一个或多个进程,一个会话中最多有一个进程组作为前台进程组。内核通过一个称为进程组ID(PGID)的数字来标识进程组。
进程
对多个资源(地址空间、一个或多个线程、套接字等)进行分组的抽象,内核通过/proc/self为当前进程向你公开这些资源。内核通过一个叫作进程ID(PID)的数字来标识一个进程。
线程
由内核以进程的形式实现。也就是说,没有专门的数据结构来表示线程。相反,线程是与其他进程共享某些资源(如内存或信号处理程序)的进程。内核通过线程ID(TID)和线程组ID(TGID)来标识一个线程,共享的TGID值意味着一个多线程进程(在用户空间,还有内核线程,但这超出了本书讨论的范围)。
任务
在内核中,有一个名为task_struct的数据结构—在sched.h(https://oreil.ly/nIgz8)中定义—它构成了实现进程和线程的基础。该数据结构捕获与调度相关的信息、标识符(如PID和TGID)、信号处理程序以及其他信息(例如与性能和安全性相关的信息)。简而言之,前面提到的所有单元都派生或锚定在任务中,但是,任务不会在内核之外公开。
我们将在第6章看到会话、进程组和进程的作用,并学习如何管理它们,它们将在第9章再次出现在容器的上下文中。
让我们来看看这些概念的实际应用:
❶bash shell进程的PID、PGID和SID为6756。从ls -al /proc/6756/task/6756/中,我们可以收集任务级别的信息。
❷ps进程的PID/PGID 6790和shell的SID相同。
我们在前面提到过,在Linux中,任务数据结构有一些与调度相关的信息。这意味着在任何给定的时间,进程都处于某种状态,如图2-2所示。
图2-2:Linux进程状态
严格地说,进程状态稍微复杂一些。例如,Linux区分了可中断睡眠和不可中断睡眠,还有僵尸态(在这种状态下,它失去了父进程)。如果你对细节感兴趣,请查看文章“Process States in Linux”(https://oreil.ly/XBXbU)。
不同的事件会导致状态转换。例如,一个正在运行的进程在执行一些I/O操作(比如从文件中读取)时可能会转换到等待态,并且无法继续执行(离开C P U)。
在快速了解了进程管理之后,让我们研究一个相关的主题:内存。