https://github.com/rust-lang/futures-rs/tree/0.3.5
futures-rs是rust官方提供的一个类库,它是Rust异步编程的基础。包括关键trait的定义如Stream,以及宏如join!, select!以及各种future组合子用来控制异步流程。
futures-rs 中定义的 future 类型是标准库中 future 的原始实现。Rust 将核心的 Future trait 移入标准库中并改为 std::future::Future 以实现 async/await 语法。在某种意义上讲,std::future::Future 可以看作是 futures::future::Future 的最小子集。
├── examples //包含两个demo
├── futures //统一对外提供的接口,提供异步编程的核心抽象,使用的是下面的子类库
├── futures-channel //异步通信channel实现:包含onshot和mpsc
├── futures-core //futures库的核心trait和type
├── futures-executor //异步任务执行器
├── futures-io //AsyncRead AsyncWrite AsyncSeek AsyncBufRead等trait
├── futures-macro //join! try_join! select! select_biased!宏实现
├── futures-sink //Sink trait
├── futures-task //处理task的工具,如FutureObj/LocalFutureObj struct、 Spawn/LocalSpawn ArcWake trait、
├── futures-test //用于测试futures-rs的通用工具类库(非测试用例)
├── futures-util //通用工具类库、扩展trait(如AsyncReadExt、SinkExt、SpawnExt)
cargo.toml
futures = { version = "0.3.5", features = ["thread-pool"] }
main.rs
use futures::channel::mpsc;
use futures::executor;
use futures::executor::ThreadPool;
use futures::StreamExt;
fn main() {
let pool = ThreadPool::new().expect("Failed to build pool");
let (tx, rx) = mpsc::unbounded::<i32>();
// 使用async块创建一个future,返回一个Future的实现
// 此时尚未提供executor给这个future,因此它不会运行
let fut_values = async {
// 创建另外一个async块,同样会生成Future的实现,
// 它在父async块里面,因此会在父async块执行后,提供executor给子async块执行
// executor连接是由Future::poll的第二个参数std::task::Context完成,
// 它代表了我们的executor,子async块生成的Future实现它能被polled(使用父async块的executor)
let fut_tx_result = async move {
(0..100).for_each(|v| {
tx.unbounded_send(v).expect("Failed to send");
})
};
// 使用thread pool 的spawn方法传输生成的future
pool.spawn_ok(fut_tx_result);
let fut_values = rx
.map(|v| v * 2)
.collect();
//使用async块提供的executue去等待fut_values完成
fut_values.await
};
// 真正的去调用上面的fut_values future,执行它的poll方法和Future里的子future的poll方法,最终驱动fut_values被驱动完成,返回结果
let values: Vec<i32> = executor::block_on(fut_values);
println!("Values={:?}", values);
}
futures/src/lib.rs
可以看到对外提供的api种类繁多,我们实际用到的可能只是一小部分,stjepang将其中的一部分抽取出来,形成了一个轻量级的futures版本,详见https://github.com/stjepang/futures-lite.git
pub mod channel {
pub use futures_channel::oneshot;
#[cfg(feature = "std")]
pub use futures_channel::mpsc;
}
pub mod executor {
pub use futures_executor::{
BlockingStream,
Enter, EnterError,
LocalSpawner, LocalPool,
block_on, block_on_stream, enter,
};
#[cfg(feature = "thread-pool")]
pub use futures_executor::{ThreadPool, ThreadPoolBuilder};
}
pub mod future {
pub use futures_core::future::{
Future, TryFuture, FusedFuture,
};
#[cfg(feature = "alloc")]
pub use futures_core::future::{BoxFuture, LocalBoxFuture};
pub use futures_task::{FutureObj, LocalFutureObj, UnsafeFutureObj};
pub use futures_util::future::{
lazy, Lazy,
maybe_done, MaybeDone,
pending, Pending,
poll_fn, PollFn,
ready, ok, err, Ready,
join, join3, join4, join5,
Join, Join3, Join4, Join5,
select, Select,
try_join, try_join3, try_join4, try_join5,
TryJoin, TryJoin3, TryJoin4, TryJoin5,
try_select, TrySelect,
Either,
OptionFuture,
FutureExt,
FlattenStream, Flatten, Fuse, Inspect, IntoStream, Map, Then, UnitError,
NeverError,
TryFutureExt,
AndThen, ErrInto, FlattenSink, IntoFuture, MapErr, MapOk, OrElse,
InspectOk, InspectErr, TryFlattenStream, UnwrapOrElse,
};
#[cfg(feature = "alloc")]
pub use futures_util::future::{
join_all, JoinAll,
select_all, SelectAll,
try_join_all, TryJoinAll,
select_ok, SelectOk,
};
#[cfg(feature = "alloc")]
pub use futures_util::future::{
abortable, Abortable, AbortHandle, AbortRegistration, Aborted,
};
#[cfg(feature = "std")]
pub use futures_util::future::{
Remote, RemoteHandle,
CatchUnwind, Shared,
};
}
pub mod io {
pub use futures_io::{
AsyncRead, AsyncWrite, AsyncSeek, AsyncBufRead, Error, ErrorKind,
IoSlice, IoSliceMut, Result, SeekFrom,
};
#[cfg(feature = "read-initializer")]
pub use futures_io::Initializer;
pub use futures_util::io::{
AsyncReadExt, AsyncWriteExt, AsyncSeekExt, AsyncBufReadExt, AllowStdIo,
BufReader, BufWriter, Cursor, Chain, Close, copy, Copy, copy_buf, CopyBuf,
empty, Empty, Flush, IntoSink, Lines, Read, ReadExact, ReadHalf,
ReadLine, ReadToEnd, ReadToString, ReadUntil, ReadVectored, repeat,
Repeat, ReuniteError, Seek, sink, Sink, Take, Window, Write, WriteAll, WriteHalf,
WriteVectored,
};
}
pub mod lock {
#[cfg(feature = "bilock")]
pub use futures_util::lock::{BiLock, BiLockAcquire, BiLockGuard, ReuniteError};
#[cfg(feature = "std")]
pub use futures_util::lock::{MappedMutexGuard, Mutex, MutexLockFuture, MutexGuard};
}
pub mod sink {
pub use futures_sink::Sink;
pub use futures_util::sink::{
Close, Flush, Send, SendAll, SinkErrInto, SinkMapErr, With,
SinkExt, Fanout, Drain, drain,
WithFlatMap,
};
#[cfg(feature = "alloc")]
pub use futures_util::sink::Buffer;
}
pub mod stream {
pub use futures_core::stream::{
Stream, TryStream, FusedStream,
};
#[cfg(feature = "alloc")]
pub use futures_core::stream::{BoxStream, LocalBoxStream};
pub use futures_util::stream::{
iter, Iter,
repeat, Repeat,
empty, Empty,
pending, Pending,
once, Once,
poll_fn, PollFn,
select, Select,
unfold, Unfold,
try_unfold, TryUnfold,
StreamExt,
Chain, Collect, Concat, Enumerate, Filter, FilterMap, FlatMap, Flatten,
Fold, Forward, ForEach, Fuse, StreamFuture, Inspect, Map, Next,
SelectNextSome, Peek, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile,
Then, Zip,
TryStreamExt,
AndThen, ErrInto, MapOk, MapErr, OrElse,
InspectOk, InspectErr,
TryNext, TryForEach, TryFilter, TryFilterMap, TryFlatten,
TryCollect, TryConcat, TryFold, TrySkipWhile,
IntoStream,
};
#[cfg(feature = "alloc")]
pub use futures_util::stream::{
// For StreamExt:
Chunks, ReadyChunks,
};
#[cfg(feature = "alloc")]
pub use futures_util::stream::{
FuturesOrdered,
futures_unordered, FuturesUnordered,
// For StreamExt:
BufferUnordered, Buffered, ForEachConcurrent, SplitStream, SplitSink,
ReuniteError,
select_all, SelectAll,
};
#[cfg(feature = "std")]
pub use futures_util::stream::{
// For StreamExt:
CatchUnwind,
};
#[cfg(feature = "alloc")]
pub use futures_util::stream::{
// For TryStreamExt:
TryBufferUnordered, TryForEachConcurrent,
};
#[cfg(feature = "std")]
pub use futures_util::stream::IntoAsyncRead;
}
pub mod task {
pub use futures_core::task::{Context, Poll, Waker, RawWaker, RawWakerVTable};
pub use futures_task::{
Spawn, LocalSpawn, SpawnError,
FutureObj, LocalFutureObj, UnsafeFutureObj,
};
pub use futures_util::task::noop_waker;
#[cfg(feature = "std")]
pub use futures_util::task::noop_waker_ref;
#[cfg(feature = "alloc")]
pub use futures_util::task::{SpawnExt, LocalSpawnExt};
#[cfg(feature = "alloc")]
pub use futures_util::task::{waker, waker_ref, WakerRef, ArcWake};
pub use futures_util::task::AtomicWaker;
}
pub mod never {
pub use futures_util::never::Never;
}