【问题标题】:Write while multiple readers are reading from different threads in Rust在多个读者从 Rust 中的不同线程读取时写入
【发布时间】:2020-07-11 16:38:42
【问题描述】:

我知道我可以使用 RwLock 来等待读取线程完成读取,尽管我想知道是否可以在读者以非原子方式阅读时写入数据(我并不关心读者是否获得旧副本数据或新数据,只要内存得到更新) 这在安全(或不安全的锈蚀)中是否可行?

关于我的具体问题的更多信息:我有一个可能需要很长时间才能写入的对象,但我希望让读者不断地阅读它。

编辑:更具体地说,我有一个包含不同对象的缓存。这些对象只保存一个字节 (u8) 数组。这个字节数组需要从不同的线程读取和写入(写入会解析一个大而繁琐的结构并将各种字段转换为字节数组)。

【问题讨论】:

  • 如果写入对象需要“很长时间”,您将如何防止读者获得部分更新的副本?
  • 在我的代码中,读者是否得到一个部分更新的对象并不重要,读者只需要对象的一些状态,而不是最新的状态。该对象也是静态大小的,并且不指向任何外部存储器,因此不会因每次运行 write 函数时写入的数据不同而产生任何冲突。
  • 你确定在这些长写的中间状态总是一致吗?也许您可以提供更多关于您正在做什么的详细信息。
  • 我确定它是一致的,在上面添加了更多细节^^^

标签: multithreading rust race-condition


【解决方案1】:

这是arc-swap crate 的一个很好的用例,它允许您以原子方式将一个Arc 换成另一个。每次您希望创建数据的新版本时,您都会创建数据的克隆并将新版本放入Arc,替换旧的Arc。需要读取的代码可以克隆到当前ArcSwap中的Arc,一旦没有旧版本的句柄,旧版本就会被销毁。

如果您需要从多个位置修改数据,您应该使用Mutex 使用以下模式。

  1. 您有一个额外的版本用于存储在Mutex 中的更新。
  2. 当您希望更新数据时,锁定互斥锁并进行更改。
  3. 克隆存储在Mutex 中的对象并将其放入ArcSwap
  4. 然后解锁互斥锁。

任何希望读取数据的代码都将从ArcSwap 克隆,并且永远不会触及Mutex。将Arc 与新版本交换后,解锁互斥锁很重要。

【讨论】:

  • 哇,几率有多大!您在 rust 用户论坛上回答了我关于 AsyncReaders 的其他问题。我一定会cargo add arc-swap 在我的缓存系统中使用。
猜你喜欢
  • 1970-01-01
  • 2014-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
相关资源
最近更新 更多