一、核心结论
在 Linux 下,条件变量(pthread_cond)+ 互斥锁 是实现「线程阻塞等待变量变化、完全不占用 CPU」的唯一标准方案。线程休眠时不参与调度,CPU 占用为 0;变量变化时可被立即唤醒。
二、核心原理
- 阻塞等待
pthread_cond_wait 会自动释放锁并让线程进入休眠阻塞态,CPU 占用率 0%。
2.唤醒机制
修改变量后调用 pthread_cond_signal,内核立即唤醒等待线程。
3.安全保证
互斥锁保护共享变量,避免多线程竞争与脏读。
4.伪唤醒防护
必须用 while 循环判断条件,而非 if。
三、最简可运行 C 代码
C
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 三要素:锁 + 条件变量 + 等待变量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int flag = 0;
// 等待线程:阻塞,0 CPU
void *wait_task(void *arg)
{
while (1)
{
pthread_mutex_lock(&mutex);
// 阻塞等待 flag 变为 1
while (flag == 0)
{
pthread_cond_wait(&cond, &mutex);
}
// 被唤醒
printf("线程被唤醒\n");
flag = 0;
pthread_mutex_unlock(&mutex);
}
return NULL;
}
// 唤醒接口:修改变量并唤醒
void trigger(void)
{
pthread_mutex_lock(&mutex);
flag = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
// 测试主线程
int main(void)
{
pthread_t tid;
pthread_create(&tid, NULL, wait_task, NULL);
while (1)
{
sleep(2);
trigger();
}
return 0;
}
四、Linux 编译与运行
1)编译(必须加 -pthread)
Bash
gcc cond.c -o cond -pthread
2)运行
Bash
./cond
3)运行效果
Plain
线程被唤醒
线程被唤醒
线程被唤醒
...
4)查看 CPU(关键验证)
新开终端执行:
Bash
top -p $(pidof cond)
等待线程 CPU 占用:0%
五、极简使用模板(工程直接复制)
C
// 全局定义
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int ready = 0;
// 等待
void wait_ready(void)
{
pthread_mutex_lock(&mutex);
while (ready == 0)
pthread_cond_wait(&cond, &mutex);
ready = 0;
pthread_mutex_unlock(&mutex);
}
// 唤醒
void set_ready(void)
{
pthread_mutex_lock(&mutex);
ready = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
六、关键规则(必记)
-
必须配合互斥锁使用
-
必须用 while 判断条件,防止伪唤醒
-
pthread_cond_wait内部会自动解锁/重新加锁 -
休眠时不占 CPU ,唤醒时实时响应
七、适用场景
-
等待数据就绪
-
等待状态变更
-
等待事件触发
-
低功耗、高实时性线程设计