可参考官方文档
Read-copy update,可以理解为,先读数据,修改之后,一次性替换旧数据
是linux内核的同步机制,提供线程安全的并发访问
1.new 新节点
2.新节点next指针指向A
3.前置节点的next指针,指向新节点
分析
分析
1 struct foo{
2 int a;
3 char b;
4 long c;
5 };
6
7 DEFINE_SPINLOCK(foo_mutex);
8
9 void foo_read(void)
10 {
11 foo *fp = gbl_foo;
12 if( fp != NULL )
13 {
14 dosomthing(fp->a, fp->b, fp->c);
15 }
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 }
宽限期,即用来解决该问题
写线程更新完gbl_foo之后,调用synchronize_rcu(),阻塞等待至宽限期结束,之后再释放旧指针
读线程加rcu_read_lock()和 rcu_read_unlock(),并不实际加锁,而是进入宽限期
synchronize_rcu() 函数需要等待,在此之前所有调用rcu_read_lock() 函数的线程,进行rcu_read_unlock()
这意味着,所有可能持有旧指针的线程不在使用旧指针
实现上设计复杂的状态机等原理
简单可理解为,rcu_read_lock() 和 rcu_read_unlock()之间不允许线程切换,当synchronize_rcu()之后,CPU都进行至少一次线程切换即可认为宽限期已过
1 void foo_read(void)
2 {
3 rcu_read_lock();
4 foo *fp = gbl_foo;
5 if( fp != NULL )
6 dosomthing(fp->a, fp->b, fp->c);
7 rcu_read_unlock();
8 }
9
10 void foo_update(foo *new_fp)
11 {
12 spin_lock(&foo_mutex);
13 foo *old_fp = gbl_foo;
14 gbl_foo = new_fp;
15 spin_unlock(&foo_mutex);
16 synchronize_rcu();
17 kfree(old_fp);
18 }
原文:https://www.cnblogs.com/jamgun/p/15013579.html