第 53 / 120 课 · 并发、IPC 与异步 I/O。返回课程合集。
机制与资源关系
mutex 保护状态不变量,条件变量用于等待状态变化。等待条件必须在同一锁保护下用 while 重查,以处理虚假唤醒和其他消费者抢先取走资源。信号量计数的是许可,不等同于任意条件。
实际用法与观察入口
以下是操作说明;先确认执行环境、工具帮助和目标对象。设备名、PID、地址及项目名示例需要按实际替换,不能将整段命令当通用板端脚本执行。
|
输出解读与排查顺序
生产者先更新状态再通知,消费者在循环中检查。退出路径也要唤醒等待者并销毁同步对象。pthread API 常直接返回错误码,不应只读 errno。
情境推演
两个消费者同时被唤醒但只有一个任务,第二个拿到锁后条件又变为假。while 重查会继续等待,if 则可能读空队列。条件变量通知本身不储存任务。
练习与参考分析
把单次 if 等待改为 while 并解释必要性。参考结论:通知不是数据本身,真正的业务条件保存在受锁保护的共享状态中。
独立实验包
主机 Linux 的有界 C 实验;不访问真实外设,不代表板端时序或性能。 默认入口、源文件和实际运行记录都在下载包中。
实验:mutex、条件变量与信号量
查看完整代码:main.c
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t changed = PTHREAD_COND_INITIALIZER;
static int ready=0, value=0;
static void *producer(void *unused) {
(void)unused;
CHECK(pthread_mutex_lock(&lock) == 0);
value=42; ready=1;
CHECK(pthread_cond_signal(&changed) == 0);
CHECK(pthread_mutex_unlock(&lock) == 0);
return NULL;
}
int main(void) {
pthread_t worker; CHECK(pthread_create(&worker,NULL,producer,NULL) == 0);
CHECK(pthread_mutex_lock(&lock) == 0);
while (!ready) CHECK(pthread_cond_wait(&changed,&lock) == 0);
CHECK(value == 42);
CHECK(pthread_mutex_unlock(&lock) == 0);
CHECK(pthread_join(worker,NULL) == 0);
CHECK(pthread_cond_destroy(&changed) == 0);
CHECK(pthread_mutex_destroy(&lock) == 0);
puts("predicate checked under mutex; received value=42");
return 0;
}
在项目根目录执行;下载包解压后,在解压目录执行 sh run.sh。
cd 'content/posts/驱动、bootloader、文件系统/嵌入式Linux系统工程/053-mutex、条件变量与信号量/code' && sh run.sh
官方资料与版本边界
内核、工具和厂商 BSP 的支持范围需分别核对。参考资料可能对应较新版本;不要据此推定旧 BSP 支持所有接口。