7 个版本
0.2.0 | 2023 年 10 月 6 日 |
---|---|
0.1.7 | 2023 年 9 月 9 日 |
0.1.5 | 2022 年 9 月 20 日 |
#429 在 异步
每月 104 次下载
55KB
868 代码行
futures-scopes
是 futures-rs 的扩展,提供作用域。作用域可以用来生成可以引用作用域创建之前创建的栈变量的非静态 futures。作用域会将这些 futures 转发到多个底层生成器之一。这允许将多个生成器组合成一个。当作用域被丢弃时,该生成器下的所有 futures 将立即被丢弃。
由于作用域本身就是一个 Spawn
,它可以在其中生成进一步嵌套的作用域。
示例
// An async example function that has access to some kind of spawner
async fn example(spawn: &(impl Spawn + Clone + Send + 'static)) {
let counter = AtomicUsize::new(0);
// Create a scope.
// Futures spawned on `scope` can reference everything before new_relay_scope!()
let scope = new_relay_scope!();
// We spawn the new scope on the given spawn.
// This could be a ThreadPool, for example.
// It is also possible to spawn on multiple Spawns to share the work between them
//
// The scope will spawn a single future to the given Spawn.
// This future will self-replicate to fill the Spawn, but not overwhelm it either.
spawn.spawn_scope(scope);
// Create a new Spawner that spawns futures on the scope.
// `spawner` is Spawn+Clone+Send+'static,
// so another nested scope can be spawned inside our scope
// with `spawner.spawn_scope(another_nested_scope)`.
let spawner = scope.spawner();
for i in 1..=100 {
// Tell rust not to move the counter into the async fn
let counter = &counter;
let fut = async move {
for _ in 0..100 {
// `counter` is not moved into the future but referenced
// `i`, however, was moved(copied) into the future
counter.fetch_add(i, Relaxed);
}
};
// spawn the future on the scope
spawner.spawn_scoped(fut).unwrap();
}
// Wait until all futures have been finished.
// This does not block the thread, but returns a future that we can await!
scope.until_empty().await;
// Counter: 505000
println!("Counter: {}", counter.load(SeqCst));
// The scope is dropped here.
// If we wouldn't have waited for all futures to be processed,
// the drop would stop the execution of all scope-futures and drop them.
// The drop blocks the current thread only minimally
// until all currently running futures are have left their poll method
// and all futures are destroyed.
}
fn main() {
// Run `example` with a ThreadPool.
let pool = ThreadPool::new().unwrap();
block_on(example(&pool));
}
依赖
~1–7MB
~42K SLoC