[笔记分享] [OS] Linux的内核同步

Platform: msm8x60
Kernel: 2.6

介绍

内核中可能由下列原因造成并发执行:
1. 中断。可在任何时刻发生。
2. 软中断和tasklet。能在任何时候唤醒它们。
3. 内核抢占。任务可能被另一个任务抢占。
4. 睡眠。在内核里睡眠会唤醒调度程序。
5. 多处理器。两个处理器执行相同代码。

为此下面介绍解决并发的处理方法。有原子操作、自旋锁和信号量。其他我们用得较少,不做介绍了。


原子操作

内核提供了两组原子操作接口:针对整数和针对位操作。
a) 原子整数操作
最常见的用途就是实现计数器,可通过atomic_inc()和atomic_dec()实现。
原子操作通常是内联函数,往往通过汇编实现。如果某个函数本来就是原子操作,那么就被定义成一个宏。

和原子整数相关操作如下:

这里写图片描述

b) 原子位操作
位操作是对普通内存地址进行操作。虽然对位操作的内存进行访问,此位号应该为0到31,但是对位号的范围去没限制。相关操作如下:

这里写图片描述


自旋锁

自旋锁最多被一个可执行线程所持有。如果有另一个线程试图争用,那么它怎么只能进入忙等待状态,直到锁能用。这样特别耗处理器,因此自旋锁不能被持有很长时间,在短期内进行轻量级加锁,加锁时间最好小于完成两次上下文切换时间。基本使用形式如下:

Spin_lock(&lock);
……
Spin_unlock(&lock);

由上可得出,它也不能在SMP上被同时访问。
另外,自旋锁是不可递归的,但是它可用在中断处理程序中,而信号量由于会睡眠所以不能。在中断中使用自旋锁之前最好禁止中断,否则有可能新中断处理程序也会争用锁而导致死锁。当然,我们只要关闭本地中断就可以了,如果是其他cpu争用spinlock也不会妨碍本中断处理程序释放锁。所以我们一般下列函数来加锁:

这里写图片描述
这里写图片描述

Spin_lock_irqsave函数综合了lock_irq_save()和spin_lock()两个函数的功能,spin_unlock_irqrestor()也是如此。当然,如果你能确定加锁前中断是激活的,那么就不需要保存状态而直接禁止中断了,这样也能得到一些效率上的优化,函数如下:
这里写图片描述

再说说下半部和自旋锁的关系。由于下半部可以抢占进程上下文的代码,所以两者共享数据的时候,需要加锁还要禁止下半部执行。同样,由于中断可抢占下半部和进程上下文,数据共享时需获取所并禁止中断。

对于同类的tasklet不可能同时运行,所以对于同类tasklet数据共享不需保护。当和不同类别的tasklet共享数据时,需要获得锁。这里不需要禁止下半部,因为同一cpu上不会有tasklet抢占情况。

对于软中断,无论是否同种类型,在数据有共享时,都需要加锁。因为即使同种类型软中断也可能在不同cpu上同时运行。当然和tasklet一样,不用禁止下半部。

和spinlock有关操作如下:

这里写图片描述


信号量

信号量是一种睡眠锁。当一个任务试图去获取一个已经被占用的信号量时,信号量会将其推入一个等待队列,然后让其睡眠。这是cpu可做其他事情。当任务被唤醒时,获得该信号量。

信号量有如下特性:
1. 由于争用信号量在等待锁时会睡眠,所以适用于锁被长时间持有的情况。
2. 因为会睡眠,所以不能在中断上下文使用。
3. 占用信号量的同时不能占用自旋锁,因为自旋锁不能睡眠。

信号量可以同时允许任意数量的持有者,而自旋锁只有一个任务可以持有它。所以信号量分计数信号量和互斥信号量两种,一般我们用互斥信号量比较多。

信号量的实现是和体系结构相关的,结构如下:

这里写图片描述

信号量的创建可静态也可动态,一般我们动态创建用的比较多,如下
Sema_init(sem, count);

在获取信号量是,我们一般用

这里写图片描述

而不是down()函数,因为前者可被信号唤醒。

下图为信号量有关操作:
这里写图片描述
这里写图片描述

当其用作互斥信号量时,操作如下:

这里写图片描述

自旋锁和信号量

一般我们也不能对它们做太多选择,因为在中断上下文只能用自旋锁,而睡眠的时候只能用信号量。下面是两者的比较:

这里写图片描述


顺序和屏障

当我们需要指示编译器不要对给定范围的代码指令序列进行重新排序时,我们可以依靠屏障来实现。Linux提供了读或者写屏障方法:

这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值