首页 > 代码库 > 11 Linux设备驱动的并发控制
11 Linux设备驱动的并发控制
一、并发和竟态
并发:多CPU或者单CPU多进程多线程同时执行
竟态:对共享资源的同时访问
以下4中情况出现并发:
(1)多CPU
(2)单CPU多进程多线程
(3)单CPU进程与中断
(4)单CPU中断与中断
二、进程调度
1. 进程调度是按照时间片来调度的,进程A的时间片用完了,就会调用进程B
2. 可抢占与不可抢占
抢占:打断当前进程(用户态或者内核态),执行其他进程。
用户态出现抢占的时刻:
(1)系统调用返回到用户态
(2)中断来了,打断用户态进程,然后中断返回的时刻
内核态抢占:
[1]中断返回内核态,Linux操作系统会检查是否可抢占
[2]内核态进程阻塞或自己调用了schedule()函数
[3]释放锁(spin_unlock:会将preempt_count --)
内核可以分为:可抢占与不可抢占的
三、关中断
总结:
上面4中并发的情况:2,3,4三种情况可以通过关闭中断来保证不会出现竞争。
四、自旋锁
单CPU平台:自旋锁功能只是关抢占
多CPU平台:内核空间关抢占 + 标志(V)
使用自旋锁目的?
防止多个执行者同时访问共享资源
进程与进程 ->OK
进程与中断 ->进程在使用共享资源的时候,还需要关闭对应的中断
中断与中断
A中断处理函数使用自旋锁,B中断优先级高,抢占A中断,并且也使用自旋锁,此时会出现什么情况?
此时B进程会一直自旋下去
如何避免中断之间并发?
中断处理函数执行的时候,关闭IRQ异常(等价于所有的中断都关闭)
五、信号量
特点:当进程不能获取信号量,进程就会休眠
1.定义信号量
struct semaphore sem;
2.初始化信号量
sema_init(struct semaphore *sem,int value);
3.获取信号量
void down(struct semaphore *sem);//不能获取,进程进入不可中断的等待态
int down_interrupt(strct sempaphore *sem);//不能获取,进程进入可中断等待
4.释放信号量
void up(struct semaphore *sem);//唤醒所有等待当前信号量的进程
注意:信号量不能再中断处理函数中使用
六、互斥锁
(1)信号量已经可以实现互斥,为什么使用互斥锁?
信号量主要是用来实现P,V操作,实现互斥效率比互斥锁低。
(2)互斥锁与自旋锁有什么区别?
[1]互斥锁不能获得锁的时候,进程阻塞,而自旋锁不会,它会进程自旋
[2]自旋锁关抢占,互斥锁不会关抢占
(3)使用互斥锁
[1]定义互斥锁
struct mutex_lock mlock;
[2]初始化
mutex_init(struct mutex_lock *lock);
[3]获得锁
mutex_lock(struct mutex_lock *lock);
[4]释放锁
mutex_unlock(struct mutex_lock *lock);
七、原子操作
11 Linux设备驱动的并发控制