ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux中的RCU机制

2022-04-30 12:34:00  阅读:156  来源: 互联网

标签:RCU void Linux 线程 rcu 机制 数据 cpu


什么是RCU?

RCU(Read-Copy Update),顾名思义就是读-拷贝-修改,它是基于其原理命名的。对于被RCU保护的共享数据结构,读者不需要获得任何锁就可以访问它,但写者在访问它时首先拷贝一个副本,然后对副本进行修改,最后使用一个回调(callback)机制在适当的时机把指向原来数据的指针替换为新的被修改的数据。这个时机就是所有引用该数据的CPU都退出对共享数据的访问。

RCU的优点?

在面对内核中需要频繁读但是不需要频繁写的共享数据时,RCU是一种非常成功的同步机制。可以实现多线程无阻塞地读取数据,就算有线程在修改数据时读者也不会被阻塞,且读取数据的时候几乎没有额外的同步开销,同时也能排除当我们在读的时候某人正在修改数据的可能(否则的话会导致读取数据的线程可能读到更新一半的数据或者是读到一个无效的指针等等)。

RCU的缺点?

RCU的缺点在于,(1)RCU的读者可能访问旧数据,或者发现数据不一致。RCU不保证在写线程开始之后的读线程可以读取到更新后的数据,只能保证读取到的数据是旧数据或新数据,而不是修改一半的错误数据。(2)写者的性能比较糟糕。

如何确定将旧数据替换为新数据的时机?

这是RCU实现的关键。难点就在于如何判断所有的读者已经完成访问。通常把写者开始更新,到所有读者完成访问这段时间叫做宽限期(Grace Period)。

static inline void __rcu_read_lock(void)
{
	preempt_disable();
}
 
static inline void __rcu_read_unlock(void)
{
	preempt_enable();
}

线程在进入RCU读临界区时关闭了抢占,在离开读临界区时打开抢占, 这时是否度过宽限期的判断就比较简单:每个CPU都经过一次抢占。
每个CPU在时钟中断的处理函数中,都会判断当前CPU是否完成了抢占。

void rcu_check_callbacks(int cpu, int user)
{
......
	if (user || rcu_is_cpu_rrupt_from_idle()) {
		/*在用户态上下文,或者idle上下文,说明已经发生过抢占*/
		rcu_sched_qs(cpu);
		rcu_bh_qs(cpu);
	} else if (!in_softirq()) {
		/*仅仅针对使用rcu_read_lock_bh类型的rcu,不在softirq,
		 *说明已经不在read_lock关键区域*/
		rcu_bh_qs(cpu);
	}
	rcu_preempt_check_callbacks(cpu);
	if (rcu_pending(cpu))
		invoke_rcu_core();
......
}

然后向RCU汇报,该CPU已经离开了读临界区。

标签:RCU,void,Linux,线程,rcu,机制,数据,cpu
来源: https://www.cnblogs.com/csfb/p/16209875.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有