rust 如何制作最大长度为一个元素的通道?

im9ewurl  于 2022-12-19  发布在  其他
关注(0)|答案(2)|浏览(196)

我成功地使用mpsc::channel()将消息从生产者线程发送到消费者。
使用者只对最新的消息感兴趣(如果没有新消息,则使用前一次检查中的消息)。
因此,我在循环中运行使用者的try_recv(),直到它无法获取新消息,然后使用最后接收到的消息,如果没有找到新消息,则使用旧消息。
存储消费者将要丢弃的旧消息是浪费内存。
如何构建mpsc::channel()的单元素变体?
(我考虑过使用sync::Mutex<Option<MyMessage>>,但关键是消费线程阻塞的时间要尽可能短。另外,我希望所有权从生产者传递到消费者。)

jslywgbw

jslywgbw1#

您可以使用AtomicPtr来实现这一点,它的compare_exchange方法应该编译为一个简单的cmpxchg指令,允许您存储std::ptr::null或实际消息。

nzk0hqpo

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);,然后检查newNone(没有新内容)还是Some(Arc<T>)(在这种情况下,它会收到更新的配置)。
在以下位置更换新的Arc<T>时,请务必注意丢弃以前的Arc<T>的成本:X1 M13 N1 X通常比X1 M14 N1 X更昂贵。

回到std

你可以使用AtomicPtr<T>,它需要你使用unsafe,并且由于避免了引用计数,它比ArcSwap快一点。
不过,它也会遇到同样的跌落问题。

DIY双缓冲

你也可以自己动手,一个简单的双缓冲存储器就可以了。
通过存储一个普通的Option<T>,你避免了额外的分配(以及额外的释放),代价是使检查本身变慢--因为你现在可能需要检查 * 两个 * 缓冲区。

相关问题