> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man9/runqueue.9.md).

# runqueue.9

`choosethread` — 管理可运行进程队列

## 名称

`choosethread`, `procrunnable`, `remrunqueue`, `setrunqueue`

## 概要

```c
#include <sys/param.h>
```

```c
#include <sys/proc.h>
```

```c
extern struct rq itqueues[];
extern struct rq rtqueues[];
extern struct rq queues[];
extern struct rq idqueues[];

struct thread *
choosethread(void)

int
procrunnable(void)

void
remrunqueue(struct thread *td)

void
setrunqueue(struct thread *td)
```

## 描述

运行队列由四个优先级队列组成：用于中断线程的 `itqueues`、用于实时优先级进程的 `rtqueues`、用于分时进程的 `queues`，以及用于空闲优先级进程的 `idqueues`。每个优先级队列由 `NQS` 个队列头结构的数组组成。每个队列头标识一个具有相同优先级的可运行进程列表。每个队列还有一个单字，包含标识非空队列的位掩码，以协助快速选择进程。它们分别命名为 `itqueuebits`、`rtqueuebits`、`queuebits` 和 `idqueuebits`。运行队列受 `sched_lock` 互斥锁保护。

`procrunnable` 在除空闲进程外没有其他可运行进程时返回零。如果除空闲进程外至少有一个可运行进程，则返回非零值。注意，调用此函数时*不需要*持有 `sched_lock` 互斥锁。存在一个小的竞争窗口，当一个 CPU 在当前没有其他可运行进程时将进程放入运行队列，而另一个 CPU 正在调用此函数时。在这种情况下，第二个 CPU 将在注意到有可运行进程之前，在空闲循环中多走一次。这之所以可行，是因为 SMP 系统中空闲 CPU 不会被停机。如果 SMP 系统中空闲 CPU 被停机，则此竞争条件在失败情况下可能会有更严重的后果，`procrunnable` 可能必须要求获取 `sched_lock` 互斥锁。

`choosethread` 返回最高优先级的可运行线程。如果没有可运行线程，则返回空闲线程。此函数由 `cpu_switch` 和 `cpu_throw` 调用以确定切换到哪个线程。必须在持有 `sched_lock` 互斥锁时调用 `choosethread`。

`setrunqueue` 将线程 `td` 添加到适当优先级队列中相应队列的尾部。该线程必须是可运行的，即 `p_stat` 必须设置为 `SRUN`。必须在持有 `sched_lock` 互斥锁时调用此函数。

`remrunqueue` 从其运行队列中移除线程 `td`。如果 `td` 不在运行队列上，内核将 [panic(9)](/man/man9/panic.9.md)。必须在持有 `sched_lock` 互斥锁时调用此函数。

## 参见

[cpu\_switch(9)](/man/man9/mi_switch.9.md), [scheduler(9)](/man/man9/scheduler.9.md), [sleepqueue(9)](/man/man9/sleepqueue.9.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man9/runqueue.9.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
