Linux自旋锁

  • 自旋锁概念

自旋锁顾名思义首先是一把锁,另外使用这把锁的线程需要反复自我循环(loop)检测这把锁是否可用。注意与信号量区别,信号量也是一把锁,但是使用这把锁的线程检测锁不可用时,选择去睡眠,而不是自我循环。

自旋锁与信号量相同点是两者都是锁,都具备锁定特性,实现临界区代码块的同步与互斥访问。

  • 自旋锁注意事项

  1. 临界区代码不要存在睡眠情况(主要因为发生睡眠不可预知睡眠多长时间,另外长时间睡眠,导致即将进入临界区其他线程,长时间得不到自旋锁,无休止自旋,从而导致死锁),所以临界区调用导致睡眠函数,不能选择自旋锁。
  2. 保证进入临界区的线程,不发生内核抢占。(这一点不必担心,持有自旋锁情况,Linux内核不进行抢占)
  3. 临界区代码,执行时间不能太长。(因为其他线程,如果要进入话,导致自旋,过多消耗CPU资源)
  4. 选择自旋锁时,也要注意中断情况(上半部分中断(硬件中断)和下半部分中断(软中断),中断会抢占即中断到来时,打断目前临界区代码执行,转往执行中断代码),当中断要进入自旋锁保护临界区代码时,将导致线程与中断发生死锁可能。

  • 自旋锁函数

1)自旋锁头文件

<linux/spinlock.h>

2)自旋锁数据类型

spinlock_t

3)自旋锁变量静态(编译时)初始化

spinlock_t lock = SPIN_LOCK_UNLOCKED;

4)自旋锁变量动态(运行时)初始化

spinlock_t lock

spin_lock_init(&lock);

5)锁定函数

void spin_lock(spinlock_t *lock);

void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);

void spin_lock_irq(spinlock_t *lock); 禁止(屏蔽硬件中断)自旋锁,针对场合4情况

void spin_lock_bh(spinlock_t *lock);禁止(屏蔽下半部分中断)自旋锁,针对场合4情况

6)解锁函数

void spin_unlock(spinlock_t *lock);

void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);

void spin_unlock_irq(spinlock_t *lock);

void spin_unlock_bh(spinlock_t *lock);

  • 读写自旋锁

锁的用途可以明确地分为读和写。这种自旋锁为读和写分别提供了不同的锁。一个或多少任务可以并发地持有读取锁;而写入锁一次最多只能被一个任务持有,而且此时不能有并发的读操作。我们可以将读/写锁分别叫做共享(并发)/排斥锁 。

读写自旋锁相关函数

1)自旋锁头文件

<linux/rwlock.h>

2)自旋锁数据类型

rwlock_t

3)自旋锁变量静态(编译时)初始化

rwlock_t my_rwlock = RW_LOCK_UNLOCKED; 

4)自旋锁变量动态(运行时)初始化

rwlock_t my_rwlock;

rwlock_init(&my_rwlock);

5)读锁定函数

void read_lock(rwlock_t* lock);

void read_lock_irqsave(rwlock_t* lock, unsigned long flags);

void read_lock_irq(rwlock_t* lock);//禁止(屏蔽硬件中断)自旋锁,针对场合4情况

void read_lock_bh(rwlock_t* lock);//禁止(屏蔽下半部分中断)自旋锁,针对场合4情况

6)读解锁函数

void read_unlock(rwlock_t* lock);

void read_unlock_irqrestore(rwlock_t* lock, unsigned long flags);

void read_unlock_irq(rwlock_t* lock);

void read_unlock_bh(rwlock_t* lock);

6)写锁定函数

void write_lock(rwlock_t* lock);

void write_lock_irqsave(rwlock_t* lock, unsigned long flags);

void write_lock_irq(rwlock_t* lock);

void write_lock_bh(rwlock_t* lock);

void write_trylock(rwlock_t* lock);//尝试获得写自旋锁,不管是否成功,都会立即返回;

6)写解锁函数

void write_unlock(rwlock_t* lock);

void write_unlock_irqsave(rwlock_t* lock, unsigned long flags);

void write_unlock_irq(rwlock_t* lock);

void write_unlock_bh(rwlock_t* lock);






参考:http://blog.csdn.net/zhuriyuxiao/article/details/7641540

http://bdxnote.blog.163.com/blog/static/844423520124268101627/


发布了34 篇原创文章 · 获赞 5 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章