Rust 陷阱

Drop 不一定会执行

一个结构的 destructor (即 Drop)不一定保证会执行,这也是 std 移除 thread::scoped 这个 API 的原因,下面这几篇文章都对其进行了详细分析。

  • Async Rust: history strikes back.

    • Reference counting is not the end of the world. As a matter of fact, in an earlier essay I have argued that they are the price we pay to live in a civilized asynchronous world.
    • Glommio 中 ScopedTask 的效果

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      
      async fn some_async_function() {
        let shared = Rc::new(Cell::new(0));
        let s = shared.clone();
      
        let x = Task::local(async move {
            do_async_work(s).await; // used a Clone of shared state
        }); // <== task starts executing here
      
        do_more_work(shared); // <== may be still background executing here
      
        x.await; // <== but is surely done here.
      }
  • C++ vs Rust: an async Thread-per-Core story

    • The borrow checker works well for things that happen at predictable times. But once you start implementing things like an asynchronous call, or a queue of requests that will be consumed by io_uring at a later time and are stored in a on-heap array, things get more complex. Take the following code as a toy example:

使用异步特性强制分配内存

目前,async fn 无法在 Rust 稳定版本的 traits 中使用。 自 2022 年 11 月 17 日起,async-fn-in-trait 的 MVP 可在编译器工具链的夜间版本中使用,详情请参阅此处

与此同时,在稳定版工具链中可以使用 async-trait 来解决这一问题。

请注意,使用这些 trait 方法会导致每次函数调用都要进行堆分配。 对于绝大多数应用程序来说,这并不是一个 很大的代价,但在决定是否在低级函数的公共 API 中使用此功能时,应考虑到该函数预计每秒会被调用数百万次。