Linux C 条件变量阻塞线程用法:等待时CPU占用率为0

一、核心结论

在 Linux 下,条件变量(pthread_cond)+ 互斥锁 是实现「线程阻塞等待变量变化、完全不占用 CPU」的唯一标准方案。线程休眠时不参与调度,CPU 占用为 0;变量变化时可被立即唤醒。


二、核心原理

  1. 阻塞等待

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);
}

六、关键规则(必记)

  1. 必须配合互斥锁使用

  2. 必须用 while 判断条件,防止伪唤醒

  3. pthread_cond_wait 内部会自动解锁/重新加锁

  4. 休眠时不占 CPU ,唤醒时实时响应


七、适用场景

  • 等待数据就绪

  • 等待状态变更

  • 等待事件触发

  • 低功耗、高实时性线程设计

相关推荐
爱学习的小囧7 分钟前
VMware vCenter Server 9.0.2.0 资源详解+完整部署教程+下载指南+常见问题
运维·服务器·esxi·vmware·虚拟化·esxi9.0.2.0
贾斯汀玛尔斯36 分钟前
每天学一个算法--单调栈(Monotonic Stack)
运维·服务器·算法
hhb_61837 分钟前
Linux底层运维自动化挂载与磁盘分区实战指南
linux·运维·自动化
SpikeKing43 分钟前
Server - 配置 SQLBot 智能问数项目
运维·server·sqlbot
cui_ruicheng1 小时前
Linux库制作与使用(二):ELF文件与链接过程
linux·运维·服务器
ReaF_star1 小时前
【环保】CentOS 7 安装 MySQL 8 实战记录:从安装到排障一次讲清
linux·mysql·centos
怀旧,1 小时前
【Linux系统编程】18. Linux进程信号(上)
linux·运维·服务器
舰长1151 小时前
Windows服务器修改默认远程端口3389
运维·服务器
minji...2 小时前
Linux 线程同步与互斥(五) 日志,线程池
linux·运维·服务器·开发语言·c++·算法
华清远见IT开放实验室2 小时前
嵌入式系统化课程 学习内容与服务说明
linux·stm32·学习·嵌入式·全栈·虚拟仿真·测评中心