# 2.1 任务

进程是现代操作系统中最重要的概念之一，一个进程表示程序的一个执行实例。进程本身也是一个动态的概念，代表着程序一次从头到尾的执行过程，因此进程有自己的生命周期，可能处于不同的状态，这方面的资料已经非常丰富，就不在这里赘述了，感兴趣的同学[上网搜](https://www.google.com/search?q=process+state+diagram)就可以了。

然而在Linux中，进程并不是最小的执行单元，系统中最小的执行单元是线程（Thread）。但在内核层面并没有对进程与线程做显示的区分，二者统一都叫着任务（Task），区别体现在对资源的共享程度上：进程本质上是对资源的一种抽象与隔离，包括内存地址空间、文件、信号量等，Linux在通过系统调用 `clone` 创建一个新的 task 时，如果所有的资源都不共享，那么对用户而言就是创建了一个新的进程，如果除了函数调用栈（Stack）不共享、其他所有资源都共享，则创建的便是一个线程。

Linux 使用 `task_struct` 来表示一个任务，其定义如下：

```
/* file: include/linux/sched.h */
struct task_struct {
    /* 与优先级相关的字段 */
    int prio;
    int static_prio;
    int normal_prio;

    unsigned int rt_priority;

    /* 调度策略 */
    const struct sched_class *sched_class;
    /* 调度实体，调度器的调度对象，该字段用于 CFS */
    struct sched_entity se;
    /* 该字段用于 RT 调度器 */
    struct sched_rt_entity rt;
#ifdef CONFIG_CGROUP_SCHED
    struct task_group *sched_task_group;
#endif
    /* 该字段用于 DL 调度器 */
    struct sched_dl_entity dl;
}
```

`task_struct` 是一个非常大的结构体，包含了进程运行时的所有信息，这里我们只罗列出了几个与调度逻辑相关的字段，这些字段的作用在本章的后续章节中会做进一步分析。

从调度的角度来看，不同类型进程的调度需求是不一样的：

* 交互式进程（Interactive Process） 进程运行过程中需要不断通过 I/O 与用户交互，由于用户行为的速度与CPU的执行的速度有巨大落差，所以在 OS 看来这类进程大多数时间都在等待I/O事件。

  为了提升用户体验，该类进程最好能够有较好的响应时间，即一旦用户完成了操作，我们希望进程能够以最快地速度完成响应。所以对于调度器而言，如果这类进程是就绪的，那么最好立刻执行他们。也就是说，这类进程应该具备较高的优先级。
* 批处理进程（Batch Process） 这类进程几乎没有交互需求，只要他们在后台默默运行就好。用户对他们的期望是有足够大的吞吐量，因此每次被调度到时，最好都能稳稳当当运行一段时间，以便能够更好的利用CPU缓存以提升效率。
* 实时进程（Real-time Process） 这类进程对响应时间要求极高，因此一旦进程处于就绪状态，就需要立刻扔到 CPU 上执行。

在接下来的章节中，我们将详细探讨Linux对进程的调度原理，弄清楚内核如何区分不同类型的进程，并着重分析CFS调度期的实现细节。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://s3.shizhz.me/linux-sched/task.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
