如何在Rust中在线程之间传输最新状态而不使用互斥锁

3
我正在进行一个Rust项目,其中有两个不同的线程分别用于特定目的。一个是实时线程,直接与硬件接口,并保持严格的时间要求,而另一个是Web服务器线程,为查询所述硬件的当前状态提供API。
我需要一种机制,使得Web服务器线程能够从实时线程获取硬件的最新状态。这里的挑战在于避免使用互斥锁,因为实时线程不能承受被阻塞等待互斥锁的情况。
以下是我考虑过的几种解决方案及其相应的挑战:
1. `rwlock`:但是写入线程(实时线程)需要等待,如果有任何读取器锁定它。 2. 双缓冲:执行交换的线程需要对整个结构体进行可变引用,这会导致借用检查器出现问题。 3. `mpsc Channel`:如果没有进行Web请求,通道可能会很快填满,导致内存浪费。

国家报告包含哪些数据?具体有多大?这将影响可行的解决方案。 - Kevin Reid
@KevinReid 这是一个表示机器人各个部分聚合的所有状态的结构体,大约有10个f32和一些布尔值和枚举类型。 - WinKey
2个回答

2
你可以使用arc-swap crate,它提供了ArcSwap类型(以及相关类型):一种可以在无锁的方式下替换和加载的Arc

文档中提到它适用于“经常读取但很少更新”的数据,听起来与我的使用情况相反。从源代码来看,ArcSwap::store() 调用了 ArcStore::swap(),后者又调用了 wait_for_readers,听起来会阻塞。 - WinKey

1

我最终使用了大小为1的环形通道,它在底层使用了AtomicCell<Option<Box<T>>>crossbeaml中。

实时线程可以send()到通道中,该通道是原子且无锁的。然后网络线程可以从通道中recv(),或者如果通道中没有内容,则继续使用上次读取的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接