同步互斥阻塞
目的是:同一时刻,只能有1个app打开/dev/buttons
1. 原子操作 原子操作指的是在执行过程中不会被别的代码路径所中断的操作。 常用原子操作函数举例: atomic_t v = ATOMIC_INIT(0); //定义原子变量v并初始化为0 atomic_read(atomic_t *v); //返回原子变量的值 void atomic_inc(atomic_t *v); //原子变量增加1 void atomic_dec(atomic_t *v); //原子变量减少1 int atomic_dec_and_test(atomic_t *v); //自减操作后测试其是否为0,为0则返回true,否则返回false。 驱动中: static atomic_t canopen = ATOMIC_INIT(1); //定义原子变量并初始化为1 open: if (!atomic_dec_and_test(&canopen)) { atomic_inc(&canopen); return -EBUSY; } close: atomic_inc(&canopen); ---------------------------------------------------------------------------------------------------------------------------------- 2. 信号量 信号量(semaphore)是用于保护临界区的一种常用方法,只有得到信号量的进程才能执行临界区代码。 当获取不到信号量时,进程进入休眠等待状态。 定义信号量 struct semaphore sem; 初始化信号量 void sema_init (struct semaphore *sem, int val); void init_MUTEX(struct semaphore *sem);//初始化为0 static DECLARE_MUTEX(button_lock); //定义互斥锁 获得信号量 void down(struct semaphore * sem); int down_interruptible(struct semaphore * sem); int down_trylock(struct semaphore * sem); 释放信号量 void up(struct semaphore * sem); 驱动中: open: /* 获取信号量 */ down(&button_lock);//第二次打开的时候进入休眠, close: up(&button_lock);//唤醒 ----------------------------------------------------------------------------------------------------------------------- 3. 阻塞 阻塞操作 是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。 被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。 非阻塞操作 进程在不能进行设备操作时并不挂起,它或者放弃,或者不停地查询,直至可以进行操作为止。 fd = open("...", O_RDWR | O_NONBLOCK); 驱动中: open&read: if (file->f_flags & O_NONBLOCK) //非阻塞操作 { if (down_trylock(&button_lock)) return -EBUSY; } else //阻塞操作