【系统编程】条件变量
摘要:条件变量是线程同步机制,用于高效等待条件成立而非轮询,需配合互斥锁使用。核心API包括初始化(pthread_cond_init)、等待(pthread_cond_wait原子操作:解锁并阻塞,唤醒后重新加锁)、限时等待(pthread_cond_timedwait)、唤醒线程(signal唤醒单个,broadcast唤醒所有)。典型用法:线程在循环中检查条件,条件不满足时调用wait;条件
·
一、简介
1.1 本质
- 不是锁,它不能单独保护共享数据。
- 用来 阻塞线程,直到某个条件满足。
- 通常配合互斥锁使用:
- 互斥锁:保证条件检测和条件修改的互斥性。
- 条件变量:负责等待和唤醒。
- 类型:
pthread_cond_t
1.2 主要作用
- 在多线程程序中,让线程 高效等待某个条件成立,而不是不断轮询(节省 CPU 资源)。
- 提供“会合点”,实现线程之间的协调与通信。
1.3 主要 API
返回值:成功返回 0
,失败返回错误号(非 errno)。
函数 | 作用 | 关键点 |
---|---|---|
pthread_cond_init |
初始化条件变量 | 一般 attr = NULL ,或用 PTHREAD_COND_INITIALIZER 静态初始化 |
pthread_cond_destroy |
销毁条件变量 | 释放资源 |
pthread_cond_wait |
阻塞等待条件变量 | 原子操作:① 阻塞等待条件;② 自动释放互斥锁,唤醒时重新加锁 |
pthread_cond_timedwait |
限时等待条件变量 | 使用 struct timespec 绝对时间 |
pthread_cond_signal |
唤醒至少一个等待线程 | 适用于只需唤醒一个线程的场景 |
pthread_cond_broadcast |
唤醒所有等待线程 | 适用于需要通知所有线程的场景 |
二、函数详解
返回值:成功返回 0
,失败返回错误号(非 errno)。
2.1 初始化
int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);
-
cond
:条件变量指针 -
attr
:属性(通常NULL
) -
静态初始化:
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-
动态初始化:
pthread_cond_init(&cond, NULL);
2.2 销毁
int pthread_cond_destroy(pthread_cond_t *cond);
2.3 等待(阻塞)
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
-
作用:
- 阻塞等待条件变量满足
- 解锁已经加锁成功的互斥量(相当于
pthread_mutex_unlock(&mutex)
) - 当条件满足,函数返回时,重新加锁互斥量(相当于
pthread_mutex_lock(&mutex)
)
-
阻塞等待
cond
,并自动释放mutex
(原子操作,不可再分) -
被唤醒后,自动重新加锁
mutex
-
原子操作,不会发生竞争条件,不会失去 CPU
2.4 限时等待
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
abstime
是绝对时间(相对时间会导致立即超时)- 绝对时间:从 1970 年 1 月 1 日 00: 00: 00 开始,计算时间
- 示例:
time_t cur = time(NULL); struct timespec t; t.tv_sec = cur + 1; // 等待 1 秒 t.tv_nsec = 0; pthread_cond_timedwait(&cond, &mutex, &t);
2.5 唤醒线程
唤醒一个线程:
int pthread_cond_signal(pthread_cond_t *cond);
唤醒所有线程:
int pthread_cond_broadcast(pthread_cond_t *cond);
示例:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_lock(&mutex);
while (!条件满足) {
pthread_cond_wait(&cond, &mutex);
}
// 条件满足,执行任务
pthread_mutex_unlock(&mutex);
配合 signal/broadcast:
pthread_mutex_lock(&mutex);
条件已满足 = 1;
pthread_cond_signal(&cond); // 或 pthread_cond_broadcast
pthread_mutex_unlock(&mutex);
更多推荐
所有评论(0)