13

我是linux内核的新手。我的问题是关于task_struct. 我知道每个task_struct都通过指向父进程的指针来引用其父进程task_struct

查看task_struct定义中的 sched.h 后,我注意到以下内容:

struct task_struct __rcu *real_parent; /* real parent process */

我发现它引用了compiler.h。我猜“__rcu”代表“读取副本更新”

有人可以澄清语法吗?

4

2 回答 2

13

Read-copy-update是一种算法,它允许对数据结构的读取器进行并发访问,而无需锁定结构。可以在这里阅读。

如果内核是使用CONFIG_SPARSE_RCU_POINTERconfig 选项构建的,__rcu则定义include/linux/compiler.h

# define __rcu          __attribute__((noderef, address_space(4)))

这是稀疏代码分析工具的注释,可以警告程序员可能忽略的某些事情。这与 RCU 的关系在以下内容中进行了解释Documentation/RCU/checklist.txt

__rcu 稀疏检查:使用 __rcu 标记指向受 RCU 保护的数据结构的指针,如果您在没有 rcu_dereference() 变体之一的服务的情况下访问该指针,sparse 会警告您。

rcu_dereference()返回一个可以被代码安全取消引用的指针,并记录程序员使用 RCU 机制保护指针的意图,使 Sparse 等工具能够检查编程错误和遗漏。

于 2013-06-15T22:30:30.550 回答
6

RCU 代表“读取、复制、更新”。它是一种允许多个读者访问数据的算法,这些数据可以由作者同时更新甚至删除。

在 RCU 下,写入者仍然必须确保相互排斥,但读取者不会获得锁。必须注意以不违反读取完整性的方式更新共享数据结构。如果必须删除或删除某些内容,则可以与读取器并行完成该项目与数据结构的取消链接,但实际删除内存必须等到最后一个读取器完成。

不是让读者获得锁,而是通过其他方式推断读者的下落。线程可以通过加入“读取端临界区”来宣布它们浏览数据结构的意图,这不是真正的锁,而是一种全局阶段。

例如,假设某些线程在阶段 0 进入 RCU 读取端临界区。更新程序执行了删除操作并希望释放一块内存。它必须简单地等待系统中的所有线程腾出阶段 0。同时,其他读者已经在查看数据结构,但是当他们向 RCU 声明他们的意图时,他们通过输入 RCU 读取端关键来完成阶段 1 下的部分。只有阶段 0 的线程可能仍然拥有指向已删除对象的指针,因此当最后一个线程离开阶段 0 时,可以安全地删除该对象。阶段 1 中新到达的线程看不到对象,因为对象已经从数据结构中删除,所以他们没有办法找到它。

RCU 利用了我们不需要“拥有”的锁定对象的想法,以便了解诸如“没有线程可以再访问该对象”之类的信息。

于 2013-06-15T22:24:39.227 回答