【问题标题】:Sharing data structures across async closures跨异步闭包共享数据结构
【发布时间】:2020-06-07 12:57:15
【问题描述】:

我一直在尝试跨异步助手共享(只读)数据结构。我想要完成的是创建一个 Hyper 服务器,在其中我预先生成了一些可供所有请求处理程序使用的数据。

以下是 Hyper 入门指南中的示例,扩展了我正在尝试做的事情:

#[tokio::main]
async fn main() {
    let address = SocketAddr::from(([127, 0, 0, 1], 3000));

    let pages = generate_static_pages();

    let make_service = make_service_fn(|_conn| async move {
        Ok::<_, Infallible>(service_fn(|req: Request<Body>| async move {
            serve(pages, req)
        }))
    });

    let server = Server::bind(&address).serve(make_service);

    if let Err(error) = server.await {
        eprintln!("server error: {}", error);
    }
}

在我的例子中,generate_static_pages() 返回一个带有预生成页面的HashMap&lt;&amp;'static str, Bytes&gt;。不幸的是,这个哈希映射不能在编译时生成,因为这会使事情变得容易得多。现在,我很挣扎,因为pages 不能被闭包借用:“不能移出pagesFnMut 闭包中的捕获变量”

我试图传递一个引用,但这没有奏效,因为 Rust 无法推断变量的生存时间足够长以供闭包使用。然后我尝试使用.clone(),但这不起作用,因为它会在移动后在变量上被调用,但它不能。最后,我尝试用Arc 包裹,但这并没有解决它,基本上是因为同样的原因。

你会建议我做什么?谢谢!

【问题讨论】:

    标签: rust rust-tokio hyper


    【解决方案1】:

    如果您只想对页面进行不可变引用,那么您应该可以使用lazy_static crate。 lazy_static 可让您在运行时初始化静态变量 - 非常有用!

    您的代码最终会看起来像:

    use lazy_static::lazy_static;
    
    lazy_static! {
      static ref PAGES: HashMap<&'static str, Bytes> = generate_static_pages();
    }
    
    #[tokio::main]
    async fn main() {
        let address = SocketAddr::from(([127, 0, 0, 1], 3000));
    
        let make_service = make_service_fn(|_conn| async move {
            Ok::<_, Infallible>(service_fn(|req: Request<Body>| async move {
                serve(&PAGES, req)
            }))
        });
    
        let server = Server::bind(&address).serve(make_service);
    
        if let Err(error) = server.await {
            eprintln!("server error: {}", error);
        }
    }
    

    另外,这是另一个lazy_static example

    【讨论】:

    • 出于好奇,如果我确实想要可变访问,我将如何解决它?干杯!
    • 在每个节点或整个地图上使用Arc&lt;Mutex&gt; 或使用并发哈希图(例如:evmap)
    • 就像@AsyaCorbeau 所说,要允许内部可变性,您必须使用MutexRefCell。您可以将其放在Arc 中,也可以使用lazy_static。这是使用lazy_static 的示例:playground link
    • 在使用互斥锁时要小心,因为您可能会遇到一个称为“死锁”的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 2019-10-30
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多