如果你用Linux perf tool的top命令做热点纠察时,你会发现,前10名嫌疑犯里面肯定有好几个都是锁!
在进行并行多处理时,不可 避免地会遇到锁的问题,这是不可避免的,因为这一直以来也许是保护共享数据的唯一方式,被保护的区域就是临界区。而我们知道,锁的开销是巨大的,因为它不 可避免地要么等待,要么让别人等待,然而这并不是开销的本质,开销的本质在于很多锁都采用了“原子操作”这么一个技术,如此一个原子操作会对总线或者 cache一致性造成很大的影响,比如要对一个变量进行原子加1,不要认为它很简单,其实背后会有很多不希望的操作,在某架构的处理器上,首先要LOCK 总线,这意味着LOCK不解除期间,其它处理器不能访存(起码是内存的某些区域),可能还要涉及到刷cache,或者触发cache一致性操作...这还 不算最猛的打击,在某些架构上,存在内存栅栏,它会刷掉CPU的流水线,刷掉cache,几乎所有的为优化而设计的方案全部失效,当然,这是代价,收益就 是你保护了临界区。
       你要保护临界区,你要付出代价,这个代价如果用复杂的锁来支付的话,未免有点大。非要这样子吗?也许是你的数据结构设计地不好,也许是你的代码流设计地不 好,比如多个线程同时读共享数据,两个线程一个读一个写,能否采用环形缓冲区来减轻竞争呢?事实上很多诸如网卡,硬盘等共享外设驱动程序都是这么玩的,代 码只要保证读指针和写指针不相互超越即可,这样可以最小化锁的使用,当然这只是一个非常简单的例子。

设计好的数据结构和代码流程是一方面,但是这个层次不够抽象,更好的方式就是设计一种更加优化的锁。读写锁这种不对称的锁应对读者多写者少的情景是一种优 化的锁,它对读者的优待就是无需等待,只要没有写者就可以直接读,否则才等待。而对于写者,它需要等待所有读者的完成。这种读写的实现可以依赖于另一种叫 做自旋锁的机制实现,我的一个实现如下所示:

typedef struct {spinlock_t *spinlock;atomic_t readers;}rwlock_t;
static inline void rdlock(rwlock_t *lock)
{spinlock_t *lck = lock->spinlock;if (likely(!lock->readers++))spin_lock(lck);
}static inline void rdunlock(rwlock_t *lock)
{spinlock_t *lck = lock->spinlock;if (likely(!--lock->readers))spin_unlock(lck);
}static inline void wrlock(rwlock_t *lock)
{spin_lock(lock->spinlock);
}static inline void wrunlock(rwlock_t *lock)
{spin_unlock(lock->spinlock);
}

很OK,不是吗?但是最好的方案就是彻底抛弃锁,彻底不用锁。
       我曾经在设计我的转发表的时候,为了降低lock开销,我为每个CPU复制了一个局部的本地转发表,这些转发表是一致的,由路由表生成,心想这就可以避免 竞争,然而,这些转发表总要面临更新问题,如何更新它们??我最初采用的方式是采用IPI(处理器间中断),在处理函数中,停掉处理线程,然后更新数据, 最后开启线程,这样可以在处理期间避免lock。十分合理,不是吗?可是我想复杂了。
       仔细看看读写锁的写锁,它鲁莽地进行了标准锁定操作,而读锁也是在第一个读者进来的时候采用了锁定动作。这些锁定操作导致的等待可以避免吗?看看我原始的 IPI方案,停掉线程是为了防止读者读到错误的数据,实际上是将主动将执行流让位给了写者,写者先来,然后再看看读写锁中的写者,发现有读者存在时,没有 主动地让位,而只是被动地等待,这种等待很无聊!
       能否将我的方式和读写锁的方式结合呢?
       怎么结合?按照刚刚的思路,无非就是为写者是被动等待还是抢先读者做一个决策!但是它还有一个别的选择,那就是先按照自己的流程写数据,不是写原始数据, 而是写原始数据的一份拷贝(伟大的写时拷贝),然后将这件事挂在一个未竟事务链表上直接走人,等待系统发现所有的读者都完成时用链表上的数据逐个覆盖原始 数据。这是个多么好的结合,这就是伟大的RCU锁。读者的代价就是简单地标示一下有人读即可,而写者也无需等待持锁,直接写副本,写完走人,后来的事就交 给系统了....

本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1673574

Linux内核RCU(Read Copy Update)锁简析-前传相关推荐

  1. Linux内核RCU(Read Copy Update)锁简析

    在非常早曾经,大概是2009年的时候.写过一篇关于Linux RCU锁的文章<RCU锁在linux内核的演变>,如今我承认.那个时候我尽管懂了RCU锁,可是我没有能力用一种非常easy的描 ...

  2. Linux RCU锁简析

    最近遇到一个问题,大压力测试下咬狗了,定位出来跟RCU相关,还是先简单的捋一捋RCU,也好看看后面能否对RCU做些特定场景下的优化. 网上RCU相关的技术博客比较多,先列几个可供参考的: MagicB ...

  3. 浅谈Linux内核RCU机制原理

    RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用.RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数 ...

  4. linux内核rcu,linux内核rcu机制详解

    RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用.RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数 ...

  5. linux内核 RCU机制详解

    简介 RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用.RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制 ...

  6. linux内核 RCU机制概述

    简介 RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用.RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制 ...

  7. 深入linux内核架构--第五章 锁与进程间通信

    内容简介:主要讲解了Linux各个独立进程间(或线程间)相互通信的机制(主要是System V机制),由于涉及到进程间资源共享,引入资源保护问题,也就是Linux的锁. 5.1 控制机制 首先通过一个 ...

  8. linux内核RCU

    RCU背景 RCU在2002年中增加到内核中的,是一种基于互斥的同步机制,当读多写少并且读性能要求较高时候能够达到最大的效果,它总体上属于一种空间换时间的方式,用短时间内占用额外的内存来保证快速的访问 ...

  9. linux内核内存屏障,从硬件引申出内存屏障,带你深入了解Linux内核RCU

    本文简介 本文从硬件的角度引申出内存屏障,这不是内存屏障的详尽手册,但是相关知识对于理解RCU有所帮助.这不是一篇单独的文章,这是<谢宝友:深入理解Linux RCU>系列的第2篇,前序文 ...

最新文章

  1. 数论 - SGU 105 DIV3
  2. 互联网1分钟 |1120
  3. 单页应用程序的Spring Boot静态Web资源处理
  4. 关于通过反汇编查看dll的方法【转】(
  5. windows linux mysql_linux/windows环境mysql数据库安装与使用
  6. Mac osx 下配置ANT
  7. Spring Cloud Gateway (七)处理流程解析
  8. 深度学习笔记_卷积神经网络基本概念
  9. 泰安的雾霾确实有点大
  10. 中国范围的经纬度及部分城市经纬度
  11. 宇视网络视频录像机添加摄像机提示离线
  12. 用c语言编程一个滑稽图案,滑稽,用C语言搞个鼠标连点器
  13. springCloud微服务生态圈囊括—— 服务注册,服务调用,服务降级,熔断。(1)
  14. Global land use changes are four times greater than previously estimated
  15. RUNA WFE,workflow environment based on JBoss' JBPM engine
  16. Android Studio连接驱动装不上应用程序无法正常启动(oxc000007b)
  17. Spring Boot 项目鉴权的 4 种方式
  18. 我的2019年计划清单
  19. 第一周-PDCA学习模型
  20. Office2016卡顿的原因及解决方法

热门文章

  1. 掘金后端 mysql优化_vue服务端渲染项目(ssr)仿掘金、后台页面是react spa、服务层nodejs、koa、mysql编写的一套多权限内容管理系统...
  2. 这些面试用例设计,你肯定遇到过(朋友圈、电梯、发红包、支付)
  3. 程序员:进不了大厂,就“永无出头之日”了?
  4. 360怎么看电脑配置_怎么样查看电脑配置?5种方法查看电脑硬件配置好坏图文详解...
  5. java数组变量_关于java 的数组引用变量
  6. java 任务栏程序_如何在任务栏显示java程序图标
  7. papers to read
  8. 26留数及其应用(二)
  9. DenseNet细节
  10. Fashion Mnist中的softmax应用