首页 > 编程笔记 > Linux笔记 阅读:30

Linux中的进程管理(新手必看)

Linux 的内核中有许多与进程管理相关的部分,其中一些处理特定于 CPU 架构的事情(比如中断),而另一些则专注于程序的启动和调度。

在了解 Linux 细节之前,我们要注意,进程通常是基于可执行程序(或二进制文件)的面向用户的单元。另外,线程是进程上下文中的执行单元。你可能遇到过术语“多线程”,这意味着一个进程有许多并行执行,可能运行在不同的 CPU 上。

有了这个一般的观点,让我们看看 Linux 是如何做到的。

从最细粒度到最小单元,Linux 有以下内容:
1) 会话:包含一个或多个进程组,并表示带有可选 tty 附加的面向用户的高级单元。内核通过一个称为会话 ID(SID)的数字来标识会话。

2) 进程组:包含一个或多个进程,一个会话中最多有一个进程组作为前台进程组。内核通过一个称为进程组 ID(PGID)的数字来标识进程组。

3) 进程:对多个资源(地址空间、一个或多个线程、套接字等)进行分组的抽象,内核通过 /proc/self 为当前进程向你公开这些资源。内核通过一个叫作进程 ID(PID)的数字来标识一个进程。

4) 线程:由内核以进程的形式实现。也就是说,没有专门的数据结构来表示线程。相反,线程是与其他进程共享某些资源(如内存或信号处理程序)的进程。内核通过线程 ID(TID)和线程组 ID(TGID)来标识一个线程,共享的 TGID 值意味着一个多线程进程(在用户空间,还有内核线程,但这超出了本书讨论的范围)。

5) 任务:在内核中,有一个名为 task_struct 的数据结构,在 sched.h中定义,它构成了实现进程和线程的基础。该数据结构捕获与调度相关的信息、标识符(如 PID 和 TGID)、信号处理程序以及其他信息(例如与性能和安全性相关的信息)。

简而言之,前面提到的所有单元都派生或锚定在任务中,但是,任务不会在内核之外公开。

让我们来看看这些概念的实际应用:
$ ps -j
PID   PPID  SID  TTY      TIME CMD
6756  6756  6756 pts/0    00:00:00 bash ①
6790  6790  6756 pts/0    00:00:00 ps  ②

我们在前面提到过,在 Linux 中,任务数据结构有一些与调度相关的信息。这意味着在任何给定的时间,进程都处于某种状态,如下图所示。


图 1 Linux 进程状态

严格地说,进程状态稍微复杂一些。例如,Linux 区分了可中断睡眠和不可中断睡眠,还有僵尸态(在这种状态下,它失去了父进程)。不同的事件会导致状态转换,例如一个正在运行的进程在执行一些 I/O 操作(比如从文件中读取)时可能会转换到等待态,并且无法继续执行(离开 CPU)。

相关文章