Rust asynchronous programming: futures-rs

https://github.com/rust-lang/futures-rs/tree/0.3.5

Overview

Futures-rs is a class library officially provided by Rust, which is the basis of Rust asynchronous programming. Including the definition of key traits such as Stream, and macros such as join!, select! and various future combinators to control asynchronous processes.

The future type defined in futures-rs is the original implementation of future in the standard library. Rust moved the core Future trait into the standard library and changed it to std::future::Future to implement async/await syntax. In a sense, std::future::Future can be regarded as the smallest subset of futures::future::Future.

Code structure

├── 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)

Usage example

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

It can be seen that there are many types of APIs provided to the outside world, and what we actually use may only be a small part.stjepang extracts some of them to form a lightweight version of futures, see https://github.com/stjepang for details /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;
}

Guess you like

Origin blog.csdn.net/kk3909/article/details/108165605