这是关于 Rust 异步生态系统内的内存排序保证的一个相当基本的问题。但是,我似乎在任何地方都找不到明确的答案。
C++ 内存排序从基于线程的角度指定内存排序:
发布-获取排序
如果线程 A 中的原子存储标记为 memory_order_release,并且线程 B 中来自同一变量的原子加载标记为 memory_order_acquire,则从线程的角度来看,在原子存储之前发生的所有内存写入(非原子和宽松原子) A,在线程 B 中成为可见的副作用。也就是说,一旦原子加载完成,线程 B 保证可以看到线程 A 写入内存的所有内容。
各种 Rust 异步执行器支持跨线程移动任务.await
。一个自然的场景是:
Relaxed
任务 A 位于线程 1 并在变量 处执行存储x
。- 任务 A
.await
命中 - 任务 A 被移动到线程 2 并被唤醒。
Release
然后在变量处执行存储y
。 - 任务 B 位于线程 3 并在变量处执行
Acquire
加载y
。
问题是:线程 1 的存储是否保证在加载Relaxed
后在任务 B 中可见?Acquire
例如,如果线程 3 的任务 B之后Relaxed
在变量处执行了负载x
,是否可以保证任务 A 的副作用是可见的?
这应该取决于每个异步执行器的任务调度程序中同步机制的实现。任何熟悉它们的人都会受到赞赏。