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

# kern\_yield(9)

`kern_yield` — 让出当前线程执行权的函数

## 名称

`kern_yield`, `maybe_yield`, `should_yield`

## 概要

```c
void
kern_yield(int prio)

void
maybe_yield(void)

bool
should_yield(void)
```

## 描述

`kern_yield` 函数使当前运行的线程自愿但无条件地向调度器让出其执行权。`prio` 参数指定在上下文切换之前分配的调度优先级，这会影响何时恢复执行。注意，所请求的优先级将一直生效，直到线程返回用户态，之后其基本用户优先级将被恢复。`prio` 的有效值为

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

中定义的任何 `PRI_*` 值，以及以下特殊值：

**`PRI_USER`** 以线程的基本用户优先级调度线程；该值对应于 setpriority(2) nice(3)。

**`PRI_UNCHANGED`** 让出线程而不更改其优先级。

`should_yield` 函数检查自线程上次自愿上下文切换以来是否已过去足够的时间，使得让出对其他线程是一项有用的服务。当属于这种情况时返回 `true`。关于这意味着什么的详细说明，参见“使用说明”。

`maybe_yield` 函数是用于可选地让出处理器的常见任务的辅助函数。在内部，如果 `should_yield` 返回 `true`，则将调用 `kern_yield(PRI_USER)`。

## 使用说明

虽然内核支持抢占，但这通常保留给高优先级的实时或中断线程。内核工作线程和分时线程不保证能相互抢占。因此，在内核中执行的线程应与系统中的其他线程协作行事。让出函数主要供在内核中执行大量工作的线程使用。例如：`vlnru` 进程每次回收 vnode 时都会调用 `maybe_yield`。

调度器旨在识别独占 CPU 的线程，并以降低的优先级调度它们。定期让出处理器的线程将获得更频繁运行的机会。可能令人惊讶的是，根据 CPU 运行队列上其他线程的分布情况，调用 `kern_yield` 并不保证让出的线程会被移出 CPU。

考虑到上述因素，建议对使用 `kern_yield` 编写的代码进行测量，以确认其使用对相关性能或响应性指标有积极影响。切换线程上下文有非零成本，因此过于急切地让出处理器可能对性能产生负面影响。

此外，由于让出是一种协作行为，建议让出的线程在可能的情况下释放其持有的任何锁。否则，被给予运行机会的线程可能最终要等待让出的线程释放锁，这在很大程度上违背了让出的目的。

## 参见

setpriority(2), nice(3), [mi\_switch(9)](/man9/mi_switch.9.md)

## 作者

本手册页由 Mitchell Horne <mhorne@FreeBSD.org> 编写。
