本文主要是介绍[推荐] 最近学写 async/await 被 Rust 毒打的经验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
不要自作主张地返回 Poll::Pending。
只有在你调用的方法返回了 Poll::Pending 时,才能够返回 Poll::Pending。 不然,也许程序会通过编译,但运行结果不会是你想要的。如果你的 Future 只是对现有 Future 的简单包装,一般不会犯这种错误,但情况复杂了,可能会忘。
我们日常使用的 Future,如 TcpStream/channel/timer 之类,其实是与底层的 reactor 相关联的,它们在返回 Poll::Pending 的时候,同时会在 reactor 注册事件,所以才会收到通知,最终 wakeup 相应的 Future。我们自己随便返回 Poll::Pending 的时候,显然不会收到通知的。
可能是由于 Rust 选择的抽象方式的原因,我们一般只关注 Future 本身,忽略与 reactor 的联系。其他语言的话,貌似 reactor 或者叫 event loop 才是最核心的概念。
async/await 是高层 primitive,而 Poll 是低层 primitive。高层使用低层,很方便,反过来,比较麻烦,得避免。
有个感觉,async/await 普及开来的话,Poll 只有较底层的库才关心,日常只会与 async/await 打交道。 (另外,我们就算与 Poll 打交道时,其实几乎也不关心 Context 或者 Waker,感觉它们更底层。)
await 与 tokio::sync::Mutex 一起使用,需要注意死锁问题。
从某种意义上说 await 也是有「锁」的语义,至少都需要「等待」。只是 Mutex 等待别人 unlock,而 await 在等待事件发生。(tokio::sync::Mutext 的 lock() 方法返回的就是 Future,需要你 await 的。)
举个例子,lock 之后,然后 await。如果被 await 的 Future,也需要 lock,然后才能返回 Poll::Ready。这时实际上就死锁了,两个 Future 会无限等待下去。
所以呢,不要认为,我反正只用了一把锁,所以死锁是不可能的。(推
这篇关于[推荐] 最近学写 async/await 被 Rust 毒打的经验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!