linux内核 RCU机制详解【转】

本文转载自:https://blog.csdn.net/xabc3000/article/details/15335131

 简介

        RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用。RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数据的时候不对链表进行耗时的加锁操作。这样在同一时间可以有多个线程同时读取该链表,并且允许一个线程对链表进行修改(修改的时候,需要加锁)。RCU适用于需要频繁的读取数据,而相应修改数据并不多的情景,例如在文件系统中,经常需要查找定位目录,而对目录的修改相对来说并不多,这就是RCU发挥作用的最佳场景。

       Linux内核源码当中,关于RCU的文档比较齐全,你可以在 /Documentation/RCU/ 目录下找到这些文件。Paul E. McKenney 是内核中RCU源码的主要实现者,他也写了很多RCU方面的文章。他把这些文章和一些关于RCU的论文的链接整理到了一起。http://www2.rdrop.com/users/paulmck/RCU/

       在RCU的实现过程中,我们主要解决以下问题:

       1,在读取过程中,另外一个线程删除了一个节点。删除线程可以把这个节点从链表中移除,但它不能直接销毁这个节点,必须等到所有的读取线程读取完成以后,才进行销毁操作。RCU中把这个过程称为宽限期(Grace period)。

       2,在读取过程中,另外一个线程插入了一个新节点,而读线程读到了这个节点,那么需要保证读到的这个节点是完整的。这里涉及到了发布-订阅机制(Publish-Subscribe Mechanism)。

       3, 保证读取链表的完整性。新增或者删除一个节点,不至于导致遍历一个链表从中间断开。但是RCU并不保证一定能读到新增的节点或者不读到要被删除的节点。

       宽限期

        通过例子,方便理解这个内容。以下例子修改于Paul的文章。

[cpp]  view plain copy
  1. struct foo {  
  2.            int a;  
  3.            char b;  
  4.            long c;  
  5.  };  
  6.   
  7. DEFINE_SPINLOCK(foo_mutex);  
  8.   
  9. struct foo *gbl_foo;  
  10.   
  11. void foo_read (void)  
  12. {  
  13.      foo *fp = gbl_foo;  
  14.      if ( fp != NULL )  
  15.             dosomething(fp->a, fp->b , fp->c );  
  16. }  
  17.   
  18. void foo_update( foo* new_fp )  
  19. {  
  20.      spin_lock(&foo_mutex);  
  21.      foo *old_fp = gbl_foo;  
  22.      gbl_foo = new_fp;  
  23.      spin_unlock(&foo_mutex);  
  24.      kfee(old_fp);  
  25. }  
[cpp]  view plain  copy
  1. struct foo {  
  2.            int a;  
  3.            char b;  
  4.            long c;  
  5.  };  
  6.   
  7. DEFINE_SPINLOCK(foo_mutex);  
  8.   
  9. struct foo *gbl_foo;  
  10.   
  11. void foo_read (void)  
  12. {  
  13.      foo *fp = gbl_foo;  
  14.      if ( fp != NULL )  
  15.             dosomething(fp->a, fp->b , fp->c );  
  16. }  
  17.   
  18. void foo_update( foo* new_fp )  
  19. {  
  20.      spin_lock(&foo_mutex);  
  21.      foo *old_fp = gbl_foo;  
  22.      gbl_foo = new_fp;  
  23.      spin_unlock(&foo_mutex);  
  24.      kfee(old_fp);  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式小庄老师

要是觉得不错,就给我点支持吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值