gpt4 book ai didi

rust - 异步 Rust 中的多线程 - 为什么我的代码无法并行化?

转载 作者:行者123 更新时间:2023-12-05 08:19:38 24 4
gpt4 key购买 nike

我试图通过运行以下函数有意用尽 API 限制(900 次调用):

#[get("/exhaust")]
pub async fn exhaust(_pool: web::Data<PgPool>, config: web::Data<Arc<Settings>>) -> impl Responder {
let mut handles = vec![];

for i in 1..900 {
let inner_config = config.clone();
let handle = thread::spawn(move || async move {
println!("running thread {}", i);
get_single_tweet(inner_config.as_ref().deref(), "1401287393228038149")
.await
.unwrap();
});
handles.push(handle);
}

for h in handles {
h.join().unwrap().await;
}

HttpResponse::Ok()

我的机器有 16 个内核,所以我预计上面的运行速度比单线程函数快 16 倍,但事实并非如此。事实上,它的运行速度与单线程版本一样慢。

这是为什么呢?我错过了什么?

注意:移动|| async move 部分对我来说看起来有点奇怪,但我是按照编译器的建议到达那里的。由于 async closures being unstable,它不会让我把 async 放在第一个 Action 旁边。这可能是问题所在吗?

最佳答案

此代码确实会同步运行您的 async block 。 async block 创建了一个实现 Future 的类型,但需要知道的是 Future 不会自行开始运行,它们必须是await-ed 或交给执行程序运行。

调用 thread::spawn 时返回一个 Future 的闭包将不会执行它们;线程只是创建 async block 并返回。所以 async block 实际上并没有被执行,直到你在 handles 的循环中 await 它们,这将按顺序处理 future 。

解决此问题的一种方法是使用 futures 包中的 join_all 来同时运行它们。

let mut futs = vec![];

for i in 1..900 {
let inner_config = config.clone();
futs.push(async move {
println!("running thread {}", i);
get_single_tweet(inner_config.as_ref().deref(), "1401287393228038149")
.await
.unwrap();
});
}

futures::future::join_all(futs).await;

关于rust - 异步 Rust 中的多线程 - 为什么我的代码无法并行化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67866320/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com