当前位置:首页 > 科技  > 软件

如何解决“Future不能安全地在线程之间发送”的问题?

来源: 责编: 时间:2024-06-27 07:54:06 81观看
导读Rust应用程序通常使用异步库,如Tokio和Actix。这些库为异步I/O和并行计算等提供了有力的支持。然而,不同的异步库在一起使用时,有时会出现问题。当在Tokio运行的异步函数中使用Actix client时,可能会发生“error: future

Rust应用程序通常使用异步库,如Tokio和Actix。这些库为异步I/O和并行计算等提供了有力的支持。然而,不同的异步库在一起使用时,有时会出现问题。22628资讯网——每日最新资讯28at.com

当在Tokio运行的异步函数中使用Actix client时,可能会发生“error: future不能安全地在线程之间发送”的错误,这在使用Tokio和Actix库时是一个常见的问题。今天,我们来看看如何解决这个问题。22628资讯网——每日最新资讯28at.com

让我们从一个简单的代码示例开始,它只适用于Actix,不会产生任何问题:22628资讯网——每日最新资讯28at.com

use actix_web::{web, App, HttpResponse, HttpServer};use awc::Client;#[actix_rt::main]async fn main()  {    actix_rt::spawn(async {        HttpServer::new(|| {            App::new()                .service(web::resource("/hello").route(web::get().to(ok)))        })            .bind("127.0.0.1:8080")?            .run()            .await    });    let client = Client::new();    let url = "http://127.0.0.1:8080/hello";    let ret =  client.get(url).send().await.unwrap().body().await.unwrap();    println!("{:?}", ret);}async fn ok() -> HttpResponse {    HttpResponse::Ok()        .content_type("text/html; charset=utf-8")        .body("OK")}


22628资讯网——每日最新资讯28at.com

在这段代码中,我们使用Actix创建一个HTTP服务器,并使用Actix client向它发出GET请求。一切都很顺利,但是当我们试图在Tokio运行的异步函数中使用Actix client时,问题就开始了。22628资讯网——每日最新资讯28at.com

当我们尝试在Tokio运行时中调用Actix client时,我们会遇到“error: future不能安全地在线程之间发送的错误。async block创建的future不是Send。类型 awc::Client 不是Send”。这是因为Actix client不是Send,这意味着它不能在线程之间安全地传递。22628资讯网——每日最新资讯28at.com

下面是导致此错误的示例代码:22628资讯网——每日最新资讯28at.com

use actix_web::{web, App, HttpResponse, HttpServer};use awc::Client;#[actix_rt::main]async fn main()  {    actix_rt::spawn(async {        HttpServer::new(|| {            App::new()                .service(web::resource("/hello").route(web::get().to(ok)))        })            .bind("127.0.0.1:8080")?            .run()            .await    });    let r = tokio::spawn(async move {        let client = Client::new();        let url = "http://127.0.0.1:8080/hello";        client.get(url).send().await.unwrap().body().await.unwrap()    }).await.unwrap();    println!("{:?}", r);}async fn ok() -> HttpResponse {    HttpResponse::Ok()        .content_type("text/html; charset=utf-8")        .body("OK")}


22628资讯网——每日最新资讯28at.com

为了解决这个问题并使代码在Tokio中安全使用,我们可以使用来自Tokio的Oneshot机制。这种机制允许我们封装Actix client的输出,并在线程之间安全地传递它。22628资讯网——每日最新资讯28at.com

下面是用Oneshot用来解决这个问题的示例代码:22628资讯网——每日最新资讯28at.com

use actix_web::{web, App, HttpResponse, HttpServer};use awc::Client;#[actix_rt::main]async fn main()  {    actix_rt::spawn(async {        HttpServer::new(|| {            App::new()                .service(web::resource("/hello").route(web::get().to(ok)))        })            .bind("127.0.0.1:8080")?            .run()            .await    });      let (sender, receiver) = tokio::sync::oneshot::channel();    actix_rt::spawn(async move {        let client = Client::new();        let url = "http://127.0.0.1:8080/hello";        let _ = sender.send(client.get(url).send().await.unwrap().body().await.unwrap());    });    let r = tokio::spawn(async move {        receiver.await.unwrap()    }).await.unwrap();    println!("{:?}", r);    std::mem::forget(runtime);}async fn ok() -> HttpResponse {    HttpResponse::Ok()        .content_type("text/html; charset=utf-8")        .body("OK")}

本文链接:http://www.28at.com/showinfo-26-96748-0.html如何解决“Future不能安全地在线程之间发送”的问题?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 12306火车购票系统登录验证码的智能校验机制

下一篇: 转转游戏MQ重构:思考与心得之旅

标签:
  • 热门焦点
Top