你的位置:电感厂 > 基础知识功率电感

透过 Linux 内核看无锁编程

2015-10-09 20:05:21      点击次数:
上一篇:Yaffs2文件系统中对NAND Flash磨损均衡的改进 贴片电感

如果同步操作总是能在数条指令内完成,那么使用 Spin Lock 会比传统的 mutex lock 快一个数量级。Spin Lock 多用于多核系统中,适合于锁持有时间小于将一个线程阻塞和唤醒所需时间的场合。

pthread 库已经提供了对 spin lock 的支持,所以用户态程序也能很方便的使用 spin lock 了,需要包含 pthread.h 。在某些场景下,pthread_spin_lock 效率是 pthread_mutex_lock 效率的一倍多。美中不足的是,内核实现了读写 spin lock 锁,但 pthread 未能实现。

2. Lock -free 应用场景二 —— Seqlock

手表最主要最常用的功能是读时间,而不是校正时间,一旦后者成了最常用的功能,消费者肯定不会买账。计算机的时钟也是这个功能,修改时间是小概率事件,而读时间是经常发生的行为。以下代码摘自 2.4.34 内核:

清单 5. 2.4.34 seqlock 实现代码

443 void do_gettimeofday(struct timeval *tv)

444 {

……

448 read_lock_irqsave(&xtime_lock, flags);

……

455 sec = xtime.tv_sec;

456 usec += xtime.tv_usec;

457 read_unlock_irqrestore(&xtime_lock, flags);

……

466 }

468 void do_settimeofday(struct timeval *tv)

469 {

470 write_lock_irq(&xtime_lock);

……

490 write_unlock_irq(&xtime_lock);

491 }

不难发现获取时间和修改时间采用的是 spin lock 读写锁,读锁和写锁具有相同的优先级,只要读持有锁,写锁就必须等待,反之亦然。

Linux 2.6 内核中引入一种新型锁——顺序锁 (seqlock),它与 spin lock 读写锁非常相似,只是它为写者赋予了较高的优先级。也就是说,即使读者正在读的时候也允许写者继续运行。当存在多个读者和少数写者共享一把锁时,seqlock 便有了用武之地,因为 seqlock 对写者更有利,只要没有其他写者,写锁总能获取成功。根据 lock-free 和时钟功能的思想,内核开发者在 2.6 内核中,将上述读写锁修改成了顺序锁 seqlock,代码如下:

清单 6. 2.6.10 seqlock 实现代码

static inline unsigned read_seqbegin(const seqlock_t *sl)

{

unsigned ret = sl->sequence;

smp_rmb();

return ret;

}

static inline int read_seqretry(const seqlock_t *sl, unsigned iv)

{

smp_rmb();

return (iv & 1) | (sl->sequence ^ iv);

}

static inline void write_seqlock(seqlock_t *sl)

{

spin_lock(&sl->lock);

++sl->sequence;

smp_wmb();

}

void do_gettimeofday(struct timeval *tv)

{

unsigned long seq;

unsigned long usec, sec;

unsigned long max_ntp_tick;

……

do {

unsigned long lost;

seq = read_seqbegin(&xtime_lock);

……

sec = xtime.tv_sec;

usec += (xtime.tv_nsec / 1000);

} while (read_seqretry(&xtime_lock, seq));

……

tv->tv_sec = sec;

tv->tv_usec = usec;

}

int do_settimeofday(struct timespec *tv)

{

……

write_seqlock_irq(&xtime_lock);

……

write_sequnlock_irq(&xtime_lock);

clock_was_set();

return 0;

}

Seqlock 实现原理是依赖一个序列计数器,当写者写入数据时,会得到一把锁,并且将序列值加 1。当读者读取数据之前和之后,该序列号都会被读取,如果读取的序列号值都相同,则表明写没有发生。反之,表明发生过写事件,则放弃已进行的操作,重新循环一次,直至成功。不难看出,do_gettimeofday 函数里面的 while 循环和接下来的两行赋值操作就是 CAS 操作。

采用顺序锁 seqlock 好处就是写者永远不会等待,缺点就是有些时候读者不得不反复多次读相同的数据直到它获得有效的副本。当要保护的临界区很小,很简单,频繁读取而写入很少发生(WRRM--- Write Rarely Read Mostly)且必须快速时,就可以使用 seqlock。但 seqlock 不能保护包含有指针的数据结构,因为当写者修改数据结构时,读者可能会访问一个无效的指针。

3. Lock -free 应用场景三 —— RCU

在 2.6 内核中,开发者还引入了一种新的无锁机制 -RCU(Read-Copy-Update),允许多个读者和写者并发执行。RCU 技术的核心是写操作分为写和更新两步,允许读操作在任何时候无阻碍的运行,换句话说,就是通过延迟写来提高同步性能。RCU 主要应用于 WRRM 场景,但它对可保护的数据结构做了一些限定:RCU 只保护被动态分配并通过指针引用的数据结构,同时读写控制路径不能有睡眠。以下数组动态增长代码摘自 2.4.34 内核:大电流电感

  • FPGA 技术在视频处理领域的应用 视频处理综述视频处理是目前多媒体领域最热门的技术,主要分为视频编解码和目标信息识别两大类。前者为了节省视频数据的传输带宽,主要依靠传统的信息论理论,目前已经比较成熟;后者则为了提取用户信息,是了人工

  • 基于DSP通讯全桥开关电源的研究与设计 摘要:针对传统开关电源中损耗较大,超调量较大,动态性能较差等问题,提出了基于DSP的全桥软开关技术。通过Matlab仿真结果表明模糊自适应PID控制算法比传统PID控制算法在超调量

  • 电感和电感线圈的原理电感是电子电路阻止电流改变的一种性质。注意“改变”一词的物理意义,这点非常重要,有点像力学中的惯性。一个电感线圈被用在磁场中储存能量,你会发现这个现象非常重要。为了理

  • 请教如何粗略计算纽扣电池供电使用时间
  • 保持电源/负载电路组合稳定的推荐方案序列
  • 飞兆半导体集成式智能功率级模块具有更高的功率
  • uc3842问题请教
  • 英飞凌F3系列IC设计小功率辅助电源图文详述
  • 家庭自动化无线通信解决方案
  • 一种线型组网的三线制数据测量方法
  • [DCDC]OC2004开关降压型DC-DC,GPS,电动车,电源类
  • 汽车自动变速器电控单元设计
  • 一种多路输出隔离驱动电路及其在短路限流器中的