线程间
一、pthread 条件变量族(pthread_cond_*)
头文件:#include <pthread.h>
表格
⚠注意:没有
pthread_wait()这个函数,你脑子里的 wait,全称就是pthread_cond_wait,没有单独的 wait。
二、简单睡眠函数(线程自己睡,外部不能主动提前唤醒)
头文件:#include <unistd.h> / <time.h>
表格
重点:sleep /nanosleep,别的线程没有 API 可以中途叫醒它。只能等时间跑完,或者进程收到信号。 如果你需要「别的线程可以随时叫醒正在睡觉的线程」,sleep 系列做不到。
三、Linux IO 方式等待(eventfd + poll /epoll/select)
这是另一套完全独立体系,不使用 pthread_cond,不需要 mutex。 适合:单纯做 “事件通知、唤醒线程”,没有共享业务条件。
eventfd()创建一个事件 fd等待线程:
poll()/epoll_wait()/select()阻塞等待 eventfd 可读其他线程:向 eventfd 执行
write(),等待线程立刻被唤醒。
表格
优点:
不需要 pthread mutex、不需要 cond;
可以同时监听多个 fd(网络 fd + eventfd 唤醒 fd); 缺点:Linux 平台特有,不可移植。
四、容易混淆概念澄清
pthread_cond_wait:无限等;pthread_cond_timedwait:带超时时间等待。两个都必须绑定 mutex。sleep/nanosleep:时间睡眠,外部线程无法主动唤醒。eventfd+poll:IO 多路复用做唤醒,不用锁,Linux 特有。
选型速记
多线程共享队列( LAC 线程池场景)
用:
pthread_cond_wait+ mutex + while 判断条件。
需要等待,同时设置超时时间(条件变量)
用:
pthread_cond_timedwait。注意参数是绝对时间,不是 “等待多少毫秒”。
只想让线程睡一会,不需要别人中途叫醒
用:
nanosleep。
需要外部线程主动唤醒,但是没有共享业务状态,不想用锁
Linux 下优先:
eventfd + poll / epoll_wait。
踩坑记录
pthread_cond_timedwait第二个时间参数是绝对时间,不是 “等待多久”。 举例子:想等待 500ms,不能直接填 500ms;要拿系统当前时间,加上 500ms,得到未来的时刻,传入进去。
简单对比
cond_wait:睡,等别人 signal 叫醒,必须带锁,无限等
cond_timedwait:睡,等叫醒或者时间到,必须带锁,有超时
nanosleep:单纯睡觉,别人叫不醒,只能等时间到