> 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/condvar.9.md).

# condvar.9

`condvar` — 内核条件变量

## 名称

`condvar`, `cv_init`, `cv_destroy`, `cv_wait`, `cv_wait_sig`, `cv_wait_unlock`, `cv_timedwait`, `cv_timedwait_sbt`, `cv_timedwait_sig`, `cv_timedwait_sig_sbt`, `cv_signal`, `cv_broadcast`, `cv_broadcastpri`, `cv_wmesg`

## 概要

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

void
cv_init(struct cv *cvp, const char *desc)

void
cv_destroy(struct cv *cvp)

void
cv_wait(struct cv *cvp, lock)

int
cv_wait_sig(struct cv *cvp, lock)

void
cv_wait_unlock(struct cv *cvp, lock)

int
cv_timedwait(struct cv *cvp, lock, int timo)

int
cv_timedwait_sbt(struct cv *cvp, lock, sbintime_t sbt,
    sbintime_t pr, int flags)

int
cv_timedwait_sig(struct cv *cvp, lock, int timo)

int
cv_timedwait_sig_sbt(struct cv *cvp, lock, sbintime_t sbt,
    sbintime_t pr, int flags)

void
cv_signal(struct cv *cvp)

void
cv_broadcast(struct cv *cvp)

void
cv_broadcastpri(struct cv *cvp, int pri)

const char *
cv_wmesg(struct cv *cvp)
```

## 描述

条件变量与互斥锁配合使用以等待条件发生。条件变量通过 `cv_init` 创建，其中 `cvp` 是指向 `struct cv` 空间的指针，`desc` 是指向描述该条件变量的以空字符结尾字符串的指针。条件变量通过 `cv_destroy` 销毁。线程通过调用 `cv_wait`、`cv_wait_sig`、`cv_wait_unlock`、`cv_timedwait` 或 `cv_timedwait_sig` 等待条件变量。线程通过调用 `cv_signal` 唤醒一个等待者，或调用 `cv_broadcast` 或 `cv_broadcastpri` 唤醒所有等待者。除唤醒等待者外，`cv_broadcastpri` 还通过提高任何不满足条件的线程的优先级，确保所有等待者的优先级至少为 `pri`。`cv_wmesg` 返回 `cvp` 的描述字符串，该字符串由初始调用 `cv_init` 时设置。

`lock` 参数是指向 [mutex(9)](/man/man9/mutex.9.md)、[rwlock(9)](/man/man9/rwlock.9.md) 或 [sx(9)](/man/man9/sx.9.md) 锁的指针。[mutex(9)](/man/man9/mutex.9.md) 参数必须使用 `MTX_DEF` 而非 `MTX_SPIN` 初始化。线程在调用 `cv_wait`、`cv_wait_sig`、`cv_wait_unlock`、`cv_timedwait` 或 `cv_timedwait_sig` 之前必须持有 `lock`。当线程等待条件时，`lock` 在线程阻塞之前被原子地释放，然后在函数调用返回之前重新获取。此外，线程在挂起时将完全释放 `Giant` 互斥锁（即使递归持有），并在函数返回之前重新获取 `Giant` 互斥锁。`cv_wait_unlock` 函数在返回之前不会重新获取锁。注意，`Giant` 互斥锁可作为 `lock` 指定。但是，`Giant` 不能用作 `cv_wait_unlock` 函数的 `lock`。所有等待者必须传递与 `cvp` 相同的 `lock`。

当 `cv_wait`、`cv_wait_sig`、`cv_wait_unlock`、`cv_timedwait` 和 `cv_timedwait_sig` 解除阻塞时，其调用线程被设为可运行。`cv_timedwait` 和 `cv_timedwait_sig` 最多等待 `timo` / `HZ` 秒后解除阻塞并返回 `EWOULDBLOCK`；否则返回 0。如果捕获到信号，`cv_wait_sig` 和 `cv_timedwait_sig` 将以 `EINTR` 或 `ERESTART` 提前返回；如果通过 `cv_signal` 或 `cv_broadcast` 发信号，则返回 0。

`cv_timedwait_sbt` 和 `cv_timedwait_sig_sbt` 函数采用 `sbt` 参数代替 `timo`。它允许以 `sbintime_t` 形式指定相对或绝对解除阻塞时间，分辨率更高。参数 `pr` 允许指定所需的绝对事件精度。参数 `flags` 允许传递附加的 `callout_reset_sbt` 标志。

## 返回值

如果成功，`cv_wait_sig`、`cv_timedwait` 和 `cv_timedwait_sig` 返回 0。否则返回非零错误代码。

`cv_wmesg` 返回传递给 `cv_init` 的描述字符串。

## 错误

`cv_wait_sig` 和 `cv_timedwait_sig` 在以下情况失败：

**\[`EINTR`]** 捕获到信号，系统调用应被中断。

**\[`ERESTART`]** 捕获到信号，系统调用应被重启。

`cv_timedwait` 和 `cv_timedwait_sig` 在以下情况失败：

**\[`EWOULDBLOCK`]** 超时已到。

## 参见

[callout(9)](/man/man9/callout.9.md), [locking(9)](/man/man9/locking.9.md), [mtx\_pool(9)](/man/man9/mtx_pool.9.md), [mutex(9)](/man/man9/mutex.9.md), [rwlock(9)](/man/man9/rwlock.9.md), [sema(9)](/man/man9/sema.9.md), [sleep(9)](/man/man9/sleep.9.md), [sx(9)](/man/man9/sx.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/condvar.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.
