Linux下同步机制

Linux下同步机制

当Linux刚刚开始支持多处理器/SMP时,内核态需要获得BKL(Big Kernel Lock)。现在,只有很少的地方需要BKL进行保护了。

处理器数据(percpu data)(我看不懂。。。)

严格地说不算时同步机制,它可以解决一些本来需要同步机制来处理的问题,从而提高性能。
典型例子有:伙伴内存分配器中buddy system里维护的每个CPU可分配页的表(pcp list)(我不知道是什么东西);还有slab分配器中的每个CPU的可用和已被分配列表(我也不知道是什么东西)

将原先需要加锁保护的数据结构分离到每个CPU,可以在大多数情况下全速地处理本CPU地数据,不必考虑同步(为什么?我真的不懂)

可抢占内核

Linux 2.6支持抢占内核。利用task_struct中的一个计数preempt_count来控制某个程序是否可以被抢占。
调用preempt_disablepreempt_enable来控制进程能否被抢占

在内核获得自旋锁、读写锁、或者屏蔽中断的时候,抢占是关掉的(否则会进入死锁)

内核在区的CPU逻辑ID前通常需要关闭抢占,然后在使用完ID后再打开抢占
否则,在取得CPU逻辑ID和使用逻辑ID之间,若发生了抢占,进程回来的时候已经不在原来的CPU上了,获得的数据就将发生错误。

开关中断

内核使用local_irq_disable()local_irq_enable()来开关中断。
local_irq_disable()是通过设置CPU寄存器来阻塞中断,当local_irq_enanle()启动后,中断会重新到达,并不会丢失。
而函数disable_irq()是通过对中断控制器进行编程来阻断中断的发生(从源头)

关闭中断,以便保护可能被中断修改的数据。

注意:

  1. 注意关闭中断的时间,长时间的关闭会影响系统的反应性
  2. 中断关闭以后不可发生调度。因为中断关闭后也关闭了抢占,因此进程不会被动调度除去,但是主动调用schedule也是被禁止的,因为Linux的调度本身是依赖于中断的(时间片等),关闭中断的情况下进行调度很有可能不会有机会发生下一次调度。

软中断:local_bh_disable()local_bh_enable()
用来保护可能能软中断处理的数据。多鉴于网络协议栈。

原子操作

利用不同体系结构的处理器特性来实现原子操作的原语。例如atomic_readatomic_setatomic_addatomic_sub……
利用它们可以构建更复杂的同步原语(例如自旋锁等)

注意,原子操作并不是没有开销的
只有在应当使用的时候使用。

为什么要锁总线:test_and_set为原子操作,但是,在多CPU系统中,一条指令可能被拆分到多个CPU执行,从而干扰原子性。汇编时,在指令前缀加上LOCK,处理器就会把总线锁住,直到该指令执行完毕。原子操作是用多条指令完成的。

// 自增举例
long __stdcall Increment(long volatile*
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值