嵌入式学习(七)——嵌入式Linux设备驱动开发(四)

姓名:李萌怡  学号:19020100103  学院:电子工程学院

转自:https://blog.csdn.net/light_in_dark/article/details/73457722

【嵌牛导读】:对于嵌入式Linux设备的驱动开发,内核锁保护也是十分重要的一部分。本文对Linux内核锁保护做了简要的总结。

【嵌牛鼻子】:Linux内核锁

【嵌牛提问】:Linux内核锁有哪些?

【嵌牛正文】

一、Linux内核锁保护

(1)为什么要保护

如果模块中的某个全局变量可以被多个进程/中断同时访问,那么就必须要提供加锁机制进行保护。同时写是不允许的。

(2)和加锁保护相关的名词

A、临界区(critical region)

访问要保护的变量的代码段,称为临界区。临界区中同一时间只能一个人进入。临界区的代码可能分散在不同的函数中。如果要对临界区加锁,则必须保证在临界区的所有部分都加锁。如果有遗漏,则加锁是不可靠的。

B、同步(synchronization)

其实就是加锁。同步是保证临界区只进一个人的机制。

C、竞争(race condition)

如果有多个人同时进入临界区,就称为竞争。一般来说,认为出现竞争是错误的。

(3)加锁的原则

A、加锁是自愿的

内核不强迫程序加锁,但一旦使用了锁,驱动设计人员应该保证正确地使用锁,并保证在临界区的每个部分都加上锁。

B、不要用锁来实现功能

锁就是用来避免对变量同时访问,是一种保护机制。如果将加锁相关代码去掉,程序功能应该没有任何变化。

C、应该在一开始设计代码时,就考虑如何加锁

一定不要代码设计完毕后再加锁,很容易出问题。最好在设计私有结构体时,就开始考虑锁的使用。锁一般会包括到私有结构体中,根据设备的复杂程度,有可能需要多把锁。

(4)死锁

如果加锁不恰当,可能出现死锁。有两种常见的死锁情况:自死锁和ABBA死锁。

二、Linux内核中的哪些机制导致必须要加锁

换句话说,如果没有这些机制,就可以不加锁了。也就是说,如果当前内核不可能出现“同时”,则不必加锁。

可能导致同时访问变量的内核机制有:

(1)SMP

(2)中断

(3)内核抢占(preempt)

(4)schedule()

需要了解这些机制,才能够正确使用加锁函数。

三、原子变量(atomic_t)

对于i++类型的临界区,如果用普通的加锁保护,效率太低,因此内核推荐用atomic_t类型的变量来替代传统的int型变量。对atomic_t类型的变量,内核提供更简单、安全的访问。只要访问atomic_t变量,就必须使用内核提供的函数。注意!不同的处理器实现原子操作的方式不同。

#include <linux/atomic.h> //或<asm/atomic.h>

//由于atomic_t的实现和具体处理器相关,因此参考头文件arch/arm/include/asm/atomic.h

//声明并初始化atomic_t变量

atomic_t mycnt = ATOMIC_INIT(5);

//或者

atomic_set(&mycnt, 5);

//获得atomic_t中的计数

int i = atomic_read(&mycnt);

//变量的++

atomic_inc(&mycnt);

//有几个最常见的atomic函数,对应int型的操作:

atomic_add // +=

atomic_sub // -=

atomic_inc // ++

atomic_dec // --

四、自旋锁(spinlock_t)

内核中用的最多的锁,轻量级的锁,一般加解锁和等待锁的时间在ns级。

spinlock_t的特性:

(1)临界区中只能进入一个人

(2)等待的人忙等(只有SMP才会真正忙等)

(3)持有锁的人不能睡眠

结合前面讨论的内核机制,可以知道,spinlock可以针对SMP,中断和内核抢占提供保护。但schdule()不行。也就是说,如果临界区中必须调用kmalloc(size, GFP_KERNEL),或者copy_to/from_user之类可能导致睡眠的函数,则不能用spinlock保护。

#include <linux/spinlock.h>

//声明锁

spinlock_t mylock;

//使用之前要先初始化

spin_lock_init(&mylock);

(1)普通的加解锁

spin_lock(&mylock);

...  //临界区

spin_unlock(&mylock);

(2)如果临界区可能被中断处理函数打断,并影响到要保护的变量,则应该在加锁的同时关闭中断。加锁同时关中断,将CPSR的当前值存储到flags中;解锁时打开中断,并将flags的值恢复到CPSR中

unsigned long flags;

spin_lock_irqsave(&mylock, flags);

...  //临界区

spin_unlock_irqrestore(&mylock, flags);

spinlock_t的一个典型应用是保护链表;由于内核要求同一时间只能一个人访问list_head链表,因此一般要用spinlock_t保护。

五、互斥锁(mutex)

mutex锁也是内核中非常重要的锁,属于重量级的锁,等待锁的时间常常为ms级。

mutex的特性:

(1)临界区中一个人

(2)睡眠等

(3)持有锁时可以睡眠(必须确保能被唤醒)

如果临界区中包含中断处理函数的代码,由于获得mutex时可能导致睡眠,因此不能用mutex来保护。其他情况都可以。

#include <linux/mutex.h>

//声明mutex锁

struct mutex mylock;

//用之前要先初始化

mutex_init(&mylock);

//加锁和解锁

mutex_lock(&mylock);

//或者

ret = mutex_lock_interruptible(&mylock);

if (ret)

    return -ERESTARTSYS;

...  //临界区

mutex_unlock(&mylock);

六、信号量(semaphore)

2.6内核早期没有实现mutex锁,用semaphore来实现mutex锁的功能。在现在的内核中,基本上已经不用semaphore来保护临界区。如果内核中某些资源限定了访问人数(比如只允许3个人同时访问),这时候可以用semaphore进行保护。

#include <linux/semaphore.h>

//声明信号量

struct semaphore mysem;

//按照资源的限定初始化信号量

sema_init(&mysem, 3);

down(&mysem);

//或者

ret = down_interruptible(&mysem);

...  //访问受限资源的代码

up(&mysem);

七、其他的锁:

rwlock_t(读写锁,照顾读者,允许多个读者同时进入临界区,可能造成写者机饿)

seqlock_t(顺序锁,克服了写者肌饿,但允许读写同时进行,无法保护list_head等)

————————————————

版权声明:本文为CSDN博主「light_in_dark」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/light_in_dark/article/details/73457722

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容