我有一个简单的示例(configured),其中我首先使用Box :: pin()将未来转移到本地执行器中。
use std::collections::BTreeMap;
use futures::executor::LocalPool;
use futures::task::SpawnExt;
use std::sync::Arc;
async fn foo(input: i32) -> i32 {
println!("foo {}", input);
42 + input
}
fn code() {
let mut pool = LocalPool::new();
let mut map: BTreeMap<i32, _> = BTreeMap::new();
map.insert(1, Box::pin(foo(1)));
map.insert(2, Box::pin(foo(2)));
let mut two = map.get_mut(&2).unwrap();
let mut one = map.get_mut(&1).unwrap();
let spawner = pool.spawner();
spawner.spawn(async move { one.await; });
// println!("one: {} two: {}", one, two);
}
fn code2() {
let mut pool = LocalPool::new();
let mut map: BTreeMap<i32, _> = BTreeMap::new();
map.insert(1, Arc::pin(foo(1)));
map.insert(2, Arc::pin(foo(2)));
let mut two = map.get_mut(&2).unwrap();
let mut one = map.get(&1).unwrap();
let spawner = pool.spawner();
let one = Arc::get_mut(&mut one.clone());
spawner.spawn(async move { one.await; });
// println!("one: {} two: {}", one, two);
}
fn main() {
code();
}
在函数code2()中,我将其替换为Arc,因为我想使用线程池而不是localpool。 (未显示,因为在操场上不可用)。不幸的是,它与
有关error[E0308]: mismatched types
--> src/main.rs:37:28
|
37 | let one = Arc::get_mut(&mut one.clone()).unwrap();
| ^^^^^^^^^^^^^^^^ expected struct `std::sync::Arc`, found struct `std::pin::Pin`
|
= note: expected type `&mut std::sync::Arc<_>`
found type `&mut std::pin::Pin<std::sync::Arc<impl core::future::future::Future>>`
error: aborting due to previous error
将Arc
和Pin
授权的未来转移到线程池中的合适方法是什么?
答案 0 :(得分:0)
这可能不是问题。只要还有Box :: pin,也可以用弧线完成。
fn thread_pool() {
use futures::executor::ThreadPool;
use async_std::sync::Mutex;
let pool = ThreadPool::new().unwrap();
let mut map: BTreeMap<i32, _> = BTreeMap::new();
let fut = Arc::new(Mutex::new(Box::pin(async {1})));
map.insert(1,fut);
let mut one = map.get(&1).unwrap().clone();
pool.spawn(async move {
let mut guard = one.lock().await;
let x = (&mut *guard).await;
});
}
但是可能不是必需的,并且可能导致不确定的行为。例如,一旦将来完成,地图便会引用可能要访问的死去的未来。因此,正确的解决方案不是首先将未来存储在地图中。使用Box::pin
就足够了
fn thread_pool() {
use futures::executor::ThreadPool;
let mut pool = ThreadPool::new().unwrap();
let fut = Box::pin(async {1});
pool.spawn(async move {
let x :i32 = fut.await;
});
}