需要板子一起学习的可以这里购买(含资料):点击跳转
一、锁的作用
1、同步和互斥
1)同步:同一件事情的依次处理,数据的接收---> 数据的处理 --->数据的发送
2)互斥---- 防止对临界资源的竞争,在一个时刻,只允许一个任务去访问资源
2、驱动程序中锁
临界资源的保护,实现资源的互斥访问
3、死锁
防止死锁
二、自旋锁(spin lock)
1、什么是自旋锁:"原地打转"的一种锁
进程A访问资源的时候,在访问资源这前要获取自旋锁,这时候,进程B也想访问该临界资源。此时,进程B不能获取自旋锁,则进程B进入忙等待状态,直到进程A释放自旋锁,进程B才可能访问临界资源。
2、自旋锁是一种忙等待锁
得不到自旋锁的进程处于忙等待状态,不会产生阻塞,不会进入睡眠状态。
自旋锁适合于对临界资源访问的时间不长的情况。
锁必须要配对使用,有上锁就必须要有解锁。
3、使用
//头文件
#include <linux/spinlock.h>
1)定义并初始化一个自旋锁,自旋锁处于可用的状态
static spinlock_t gec6818_wdt_lock;
spin_lock_init(&gec6818_wdt_lock);
2)上锁
spin_lock(&gec6818_wdt_lock);
3)解锁
spin_unlock(&gec6818_wdt_lock);
4、自旋锁的使用注意事项
1) 上锁与解锁一定要成对使用。
2) 锁要依次使用,在释放一个锁之前,不要尝试去获取新的锁,否则,可能产生死锁。
3) 自旋锁适用于临界资源访问的时间比较短的情景。
4) 自旋锁是忙等待锁,不是睡眠锁,不会产生阻塞,所以在中断服务程序中,如果要使用锁,则可以使用自旋锁。
5) 自旋锁保护的临界代码区必须是一个原子过程(这个过程是一个连续的过程,不能被打断,也不会产生阻塞)。
6) 一般自旋锁适用于多核处理器,抢占式的内核情况
三、信号量
1、什么是信号量
信号量是一个多值的锁,如果信号量的值为4,则说明最多有四个进程可以同时获取这个信号量,并进行资源的访问。当第五个进程也想获取信号量,信号量的值为0,第五个进程就获取不到信号量,该进程就会产生阻塞并进入睡眠状态。
信号量在linux驱动程序设计中,使用的比较少,是因为在普通的驱动程序中,一般不会让几个进程同时去访问临界资源。信号量一般使用在网络驱动或者无线网卡的驱动中。
2、使用
#include <linux/semaphore.h>
1)定义一个信号量
static struct semaphore gec6818_sema;
2)初始化信号量
sema_init(&gec6818_sema,4);
3)获取一个信号量 ---P操作
down(&gec6818_sema);
4)释放一个信号量 ---V操作
up(&gec6818_sema);
3、信号量的使用注意:
1) 信号量是不能应用在中断服务程序中。
2) 信号量适用于在临界资源的时间比较长的场景。
3) 信号量使用多个进程访问对临界资源的情况下。
四、互斥锁
1、什么是互斥锁
互斥锁是信号量的特例,是一个二值的信号量,只有上锁和解锁的两种状态,互斥锁又叫互斥量,互斥体(mutex)。
2、互斥锁的使用方法
#include <linux/mutex.h>
1)定义一个互斥锁
static struct mutex gec6818_mutex;
2)初始化锁
mutex_init(&gec6818_mutex);
3)互斥锁上锁
mutex_lock(&gec6818_mutex);
4)互斥锁解锁
mutex_unlock(&gec6818_mutex);
5)销毁锁
mutex_destroy(&gec6818_mutex);
互斥锁和自旋锁的区别:
1) 自旋锁是一种忙等待锁,当进程得不到自旋锁,该进程会原地等待,并没有放弃CPU的使用权。
2)互斥锁是阻塞锁,当进程得不到互斥锁,该进程会产生阻塞,进入睡眠状态--->睡在该互斥锁的等待队列中。
3)如果访问的临界资源的时间较长,使用互斥锁,反之,使用自旋锁。
4)如果在原子上下文(中断服务程序)中,只能使用自旋锁。
觉得有帮助的话,打赏一下呗。。