1. 为什么需要并发控制?从实际案例说起
记得我刚开始做Linux驱动开发的时候,遇到过这样一个坑:一个简单的字符设备驱动,在单线程测试时一切正常,但一到多线程环境就频繁崩溃。经过两天熬夜调试才发现,原来是两个线程同时修改了设备状态寄存器,导致了数据竞争。
这种问题就是典型的并发竞争问题。在Linux驱动中,当多个执行线程(进程、线程、中断处理程序等)同时访问共享资源时,如果没有适当的保护机制,就会导致数据不一致、系统崩溃等严重后果。
我后来总结了一个简单的判断方法:如果你的驱动代码中有一个变量或硬件寄存器会被多个执行路径访问,那么你就需要考虑并发控制了。这不仅仅是理论要求,更是血的教训换来的经验。
2. 信号量:允许休眠的同步机制
2.1 信号量的核心特性
信号量是Linux驱动中最常用的同步机制之一。它的核心思想是:当一个线程想要访问共享资源时,先检查信号量的计数器。如果计数器大于0,表示资源可用,线程可以继续执行并将计数器减1;如果计数器为0,线程就会进入休眠状态,等待其他线程释放资源。
#include <linux/semaphore.h>
// 定义和初始化信号量
static struct semaphore my_sem;
sema_init(&my_sem, 1); // 初始值为1,表示二进制信号量
// 在访问共享资源前
if (down_interruptible(&my_sem)) {
// 被信号中断的处理
return -ERESTARTSYS;
}
// 临界区代码
access_shared_resource();
// 释放信号量
up(&my_sem);
2.2 三种获取信号量的方式
在实际项目中,我通常根据不同的场景选择不同的获取方式:
down():最基础的获取方式,如果信号量不可用,线程会无限期休眠。我一般只在确定等待时间不会太长的场景中使用。


385

被折叠的 条评论
为什么被折叠?



