驱动程序中的并发控制##
当一段驱动程序的代码同时被多个进程使用到时,这时就要考虑并发了。
控制并发的最好手段就是使用信号量,即在任何一个给定的时间,只有一个可执行的线程可以执行这段代码。在Linux中这被称之为临界操作。是使用信号量和P、V操作来保护临界区的。
P操作:信号量减一
V操作:信号量加一
其实Linux提供给驱动程序进行并发控制的手段一共有5种:
- 信号量
- 自旋锁
- 读/写信号量
- 读/写自旋锁
- Completions机制
信号量部分API###
信号量定义、初始化
- struct semaphore sem;
- void sema_init(struct semaphore *sem,int val)
- void init_MUTEX(struct semaphore *sem)
- void init_MUTEX_LOCKED(struct semaphore *sem)
信号量的PV操作
- void down(struct semaphore *sem)
- int down_interruptible(struct semaphore *sem)
- void up(struct semaphore *sem)
- int down_trylock(struct semaphore *sem)
读写信号量部分API###
定义、初始化
- struct rw_semaphore rw_sem
- void init_rwsem(struct rw_semaphore *sem)
获得、释放读写信号量
- void down_read(struct rw_semaphore *sem)
- int down_read_trylock(struct rw_semaphore *sem)
- void up_read(struct rw_semaphore *sem)
- 写和读相似
自旋锁部分API###
和信号量的区别
- 自旋锁是互斥设备,只能有两个值:“上锁”和“解锁”
- 在自旋锁期间,OS不会进行进程切换,只会响应中断,在中断结束后不会进行进程调度,还是返回到持有自旋锁的进程
- 如果这个锁已经被别人占用,代码就会进入一个紧凑的循环,这就是“自旋”部分。所以它是一个忙等待。
- 自旋锁用在临界区代码很短的情况下
- 持有自旋锁的进程要注意主动休眠,这很有可能是造成死锁的原因
自旋锁定义、初始化
- spinlock_t spin;
- spinlock_t spin_lock_init(spinlock_t lock)
锁定释放自旋锁
-
define spin_lock(lock) _spin_lock(lock)
-
define spin_unlock(lock) _spin_unlock(lock)
-
define spin_trylock(lock) _cond_lock(lock,_spin_trylock(lock))
Completions机制###
Compleations机制是一个轻量级机制,允许一个线程告诉另一个线程,工作已经完成。
定义、初始化
- struct completion my_completion
- init_completion(&my_completion)
常用操作:
- void wait_for_completion(struct copmletion *c)
- void completely(struct ,completion *c)
- void completely_all(struct completion * c)
到此的话,并发控制方法也介绍完毕,具体怎么弄我也没谱,可能还是要具体做起来的时候才有概念吧。现在先混个眼熟。