rcu_assign_pointer() 可以用在 rcu_read_lock() 和 rcu_read_unlock() 之间吗?

标签 c linux linux-kernel rcu

一开始,我有一个CPU核心作为写共享数据的写入器,一个核心作为读取共享数据的读取器。
我需要读者写回一些数据来共享数据。
我知道 rcu_read_lock()/rcu_read_unlock() 用于读取器获取共享数据。但我不确定读者写回共享数据会导致什么问题?

在阅读器中:

 rcu_read_lock();
 //get shared data
 //modify the data 
 rcu_assign_pointer(ptr1, ptr2)
 rcu_read_unlock();

此代码有效吗?

最佳答案

RCU 的一个相当基本的属性是多个编写器之间的协调是通过另一种机制处理的,例如传统锁。 RCU 将保证读者看到一致的数据 View ,并且他们正在使用的指针在完成之前不会被释放,但它不会对同时发生的不同线程的多个更新进行排序。

RCU 确实保证可以从读取器升级到写入器状态。这可以通过在意识到需要更新时获取自旋锁来完成。在调用 synchronize_rcu 之前必须退出 rcu_read_lock/rcu_read_unlock block ,但 call_rcu 可能会在 block 内排队回调。

不允许在 rcu_read_lock/rcu_read_unlock block 内进行阻塞,因此在此类内部使用阻塞互斥体管理编写器互斥将不起作用。

参见 kernel.org RCU read-to-write upgrade

关于rcu_assign_pointer() 可以用在 rcu_read_lock() 和 rcu_read_unlock() 之间吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46509679/

相关文章:

c++ - 使用变量与使用数字

c - 在多线程程序中使用 pthread mutex

linux - screen 终止后执行命令

c - 在内核中访问用户空间结构的成员给出了错误的值

c - 如果我使用 libnetfilter_queue 进行更改,网络数据包将被拒绝

c++ - 使用 OpenCV 复制时指定指针

c - 使用 sprintf 和 PQexecParams 重用缓冲区指针

c# - Web 服务可以在 asp.net 中运行,但不能在 IIS 中运行

c - 为什么 posix_spawn() 在 popen() 工作的地方失败?

linux - 内核虚拟内存如何映射到物理内存