linux内核同步

作者:dashijian 发布于:2014-10-21 16:41

同步就是避免并发和防止竞争条件。有关临界区的例子我就不举了,随便一本操作系统的书上都有。锁机制的提出也算解决了一些问题,我们待会再说,现在只要知道锁的使用是自愿的,非强制的。linux自身也提供了几种不同的锁机制,区别主要在于当锁被争用时,有些会简单地执行等待,而有些锁会使当前任务睡眠直到锁可用为止,这个后面细说。真正的困难在于发现并辨认出真正需要共享的数据和相应的共享区。先来说一些感性的话:大多数内核数据结构都需要加锁,如果有其他执行线程可以访问这些数据,那么就给这些数据加上某种形式的锁。如果任何其他什么东西能看到它,那么就要锁住它。简而言之,几乎访问所有的内核全局变量和共享数据都需要某种形式的同步方法。有关加锁的细节,在嵌套的锁时,要保证以相同的顺序获取锁,不要重复请求同一个锁,释放时,最好还是以获得锁的相反顺序来释放锁。加锁的粒度用来描述加锁保护的数据规模。接下来就开始讨论真正的同步方法:

       1.原子操作。就是指执行过程不被打断的操作,是 不能够被分割的指令。关于这个linux内核提供了两组原子操作接口:原子整数操作和原子位操作。好,先来说说这个原子整数操作。针对整数的原子操作只能对atomic_t类型的数据进行处理。需要说明的是,尽管linux支持的所有机器上的整形数据都是32位的,但是使用atomic_t的代码只能将该类型的数据当作24位来用,原因就不说了。使用原子操作需要的声明在asm/atomic.h中。原子整数操作列表如下;


 在编写代码的时候,能使用原子操作的时候,就尽量不要使用复杂的加锁机制,因为大多数或者100%情况下,原子操作比更复杂的同步方法相比较而言,给系统带来的开销小,对高速缓存行(cache-line)的影响也很小。

       对应于原子整数操作,还有一种原子操作就是原子位操作,它们是与体系结构相关的操作,定义在文件<asm/bitops.h>,它是对普通的内存地址进行操作的。它的参数是一个指针和一个位号,第0位是给定地址的最低有效位。这里没有想atomic_t一样的数据结构,只要指针指向任何希望的数据,就可以进行操作。原子位操作函数列表如下:

同时,内核还提供了一组与上述操作对应的非原子位函数,操作完全相同,不同在于不保证原子性且名字前缀多了两个下划线,例如与test_bit()对应的非原子形式是__test_bit().如果不需要原子操作,这时这些函数的执行效率可能更高。内核还提供了两个函数用来从指定的地址开始搜索第一个被设置(或未被设置)的位:

发表评论:

Copyright @ 2013-2015 蜗窝科技 All rights reserved. Powered by emlog