我正在制作自己的频道实现,但是std::task::Context
不清楚唤醒器是如何生成的。
我的伪造代码:
impl<T> Future for ReceiveFuture<T> {
type Output = Result<(), SendError<T>>;
fn poll(self: Pin<&mut Self>, ctx: &mut Context) -> Poll<Self::Output> {
self.reg_waker(ctx.waker().clone()); // send the waker to other side of channel
// do some polling
}
}
每次调用poll()
时是否需要注册一个新的唤醒程序?在我的代码中,由于不同的期货的组合,有很多超时和循环选择。
[我做了一个小实验on the playground,但不确定在各种设置下Tokio和async-std是否都能正常使用。
在生产代码中,我注册了一个新的唤醒程序,并在每个poll()
调用中取消了旧的唤醒程序。我不知道仅在第一次注册唤醒程序并在下一次民意测验中重用它是否安全。
给出以下顺序:
reg_waker(waker1)
f.poll()
获得Poll::Pending
f.poll()
获得Poll::Pending
waker1.wake()
是否可以保证在此之后唤醒f
?
问这个的原因:1)我有可以多重接收的流2)我的mpmc,mpsc通道实现是无锁的,在Multiplex选择中的某些通道可能用作关闭通知通道,很少获取消息。进行大量轮询(例如进行一百万次)时,将导致一百万个唤醒器被扔向另一侧(这看起来像内存泄漏)。要取消在同一将来不带锁的先前唤醒器,必须比带锁的实现更复杂的逻辑]