内核同步之自旋锁和信号量Linux认证考试

文章作者 100test 发表时间 2009:10:30 16:41:07
来源 100Test.Com百考试题网


  1. 自旋锁

  Linux内核中最常见的锁是自旋锁。一个自旋锁就是一个互斥设备,它只能有两个值:"锁定"和"解锁"。如果锁可用,则"锁定"位被设置,而代码继续进入临界区;相反,如果锁被其他进程争用,则代码进入忙循环并重复检查这个锁,直到锁可用为止。这个循环就是自旋锁的"自旋"。自旋锁最多只能被一个可执行的线程持有。如果一个执行线程试图获得一个被争用的自旋锁,那么该线程就会一直进行忙循环-旋转-等待锁重新可用。注意,同一个锁可以用在多个位置。缺点:一个被争用的自旋锁使得请求它的线程在等待锁重新可用时自旋(特别浪费处理器时间)。所以,自旋锁不应该被长时间持有。当然,可以采用另外的方式处理对锁的争用:让请求线程睡眠,直到锁重新可用时在唤醒它。但是,这里有两次明显的上下文切换,被阻塞的线程要换入或换出。因此,持有自旋锁的时间最好小于完成两次上下文切换的耗时。

  注意:

  1) 如果禁止内核被抢占,那么在编译时自旋锁会被完成剔除出内核。

  2) Linux内核实现的自旋锁是不可递归的。小心自加锁。

  3) 调试自旋锁, 加上配置选项CONFIG_DEBUG_SPINLOCK。

  4)自旋锁可以使用在中断处理程序中(此处不能使用信号量,因为它们会导致睡眠),在中断处理程序中使用自旋锁时,一定要在获取锁之前,首先禁止本地中断 (在当前处理器上的中断请求),否则中断处理程序就会打断正持有锁的内核代码,有可能试图去争用这个已经被持有的自旋锁。

  5) 加锁是对数据不是对代码。

  6) 所有自旋锁的等待在本质上都是不可中断的。

  1.1. 自旋锁API介绍自旋锁实现与体系结构密切相关,定义在<.linux/spinlock.h>.中。在编译时对自旋锁的初始化:

  spinlock_t my_lock=SPIN_LOCK_UNLOCKED.

  或者在运行时:

  void spin_lock_init(spinlock_t *lock).

  进入临界区:

  spin_lock(&.my_lock).

  /*访问数据*/

  spin_unlock(&.my_lock).

  内核提供禁止中断同时请求锁的接口:

  spinlock_t my_lock=SPIN_LOCK_UNLOCKED.

  unsigned long flags.

  spin_lock_irqsave(&.my_lock, flags).

  /*访问数据*/

  spin_unlock_irqrestore(&.my_lock, flags).函数spin_lock_irqsave保存了中断的当前状态,并禁止了本地中断,然后在获取指定的锁;函数 spin_unlock_irqrestore对指定的锁解锁,然后让中断恢复到加锁前的状态。

  内核提供的自旋锁的接口:

  void spin_lock_irq (spinlock_t *lock).

  void spin_unlock_irq (spinlock_t *lock).

  void spin_lock_bh (spinlock_t *lock).

  void spin_unlock_bh (spinlock_t *lock).

  如果能够确保没有任何其他代码禁止本地处理器的中断,也就是说,能够确保在释放自旋锁时应该启用中断,这可以使用spin_lock_irq函数,而无需跟踪标志。函数spin_lock_bh在获得锁之前禁止软件中断,但是会让硬件中断保持打开。


相关文章


gentoo系统启动初始化Linux认证考试
linux下通过rsync工具实现的增量备份Linux认证考试
各个Linux版本的本地root密码破解方法Linux认证考试
ubuntu下安装Kdevelop和qt4Linux认证考试
内核同步之自旋锁和信号量Linux认证考试
linux认证:linux虚拟机添加硬盘Linux认证考试
linux认证辅导:linux下启动informix服务Linux认证考试
Linux认证复习题100道含答案125(1)Linux认证考试
Linux认证复习题100道含答案125(2)Linux认证考试
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛