我成功地使用mpsc::channel()
将消息从生产者线程发送到消费者。
使用者只对最新的消息感兴趣(如果没有新消息,则使用前一次检查中的消息)。
因此,我在循环中运行使用者的try_recv()
,直到它无法获取新消息,然后使用最后接收到的消息,如果没有找到新消息,则使用旧消息。
存储消费者将要丢弃的旧消息是浪费内存。
如何构建mpsc::channel()
的单元素变体?
(我考虑过使用sync::Mutex<Option<MyMessage>>
,但关键是消费线程阻塞的时间要尽可能短。另外,我希望所有权从生产者传递到消费者。)
2条答案
按热度按时间jslywgbw1#
您可以使用
AtomicPtr
来实现这一点,它的compare_exchange
方法应该编译为一个简单的cmpxchg
指令,允许您存储std::ptr::null
或实际消息。nzk0hqpo2#
有相当多的可能性,各种权衡。
我推荐
arc-swap
机箱(见下文),因为它有一个安全和快速的接口,如果性能很关键的话,我推荐DIY双缓冲方法。标准::多位点循环
std::mpsc
还有第二个选项:X1 M2 N1 X函数创建有界信道,其中当信道满时发送方阻塞,直到接收方拾取消息。我认为它不适合你的使用情况。
时雄监视频道
时雄生态系统具有专为传播配置更改而设计的
watch
通道。不幸的是,它是为多个使用者设计的,因此使用者借用了这些消息:没有所有权的转移。
弧交换
我相信
arc-swap
板条箱可能更接近你所需要的,顾名思义,它提供了一个Atomic<Arc<T>>
的道德等价物。您可以使用
ArcSwapOption<T>
来获得Atomic<Option<Arc<T>>>
的等效项,使用者只需执行let new = atomic.swap(None);
,然后检查new
是None
(没有新内容)还是Some(Arc<T>)
(在这种情况下,它会收到更新的配置)。在以下位置更换新的
Arc<T>
时,请务必注意丢弃以前的Arc<T>
的成本:X1 M13 N1 X通常比X1 M14 N1 X更昂贵。回到
std
你可以使用
AtomicPtr<T>
,它需要你使用unsafe
,并且由于避免了引用计数,它比ArcSwap
快一点。不过,它也会遇到同样的跌落问题。
DIY双缓冲
你也可以自己动手,一个简单的双缓冲存储器就可以了。
通过存储一个普通的
Option<T>
,你避免了额外的分配(以及额外的释放),代价是使检查本身变慢--因为你现在可能需要检查 * 两个 * 缓冲区。