rust异步编程:futures-rs

文章目录

    • 概述
    • 代码结构
    • 使用示例
    • futures

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

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;
}

你可能感兴趣的:(rust,rust,异步编程)