跳到主要内容

Builder

搜索

结构体 Builder 

源代码
pub struct Builder { /* 私有字段 */ }
展开描述

使用自定义配置值构建 Tokio 运行时。

可以按链式调用各方法来设置配置值。运行时通过调用 build 来构造。

通过 Builder::new_multi_threadBuilder::new_current_thread 获取 Builder 的新实例。

有关各种配置选项的详细信息,请参阅函数级文档。

§示例

use tokio::runtime::Builder;

fn main() {
    // 构建运行时
    let runtime = Builder::new_multi_thread()
        .worker_threads(4)
        .thread_name("my-custom-name")
        .thread_stack_size(3 * 1024 * 1024)
        .build()
        .unwrap();

    // 使用运行时 ...
}

实现§

源代码§

impl Builder

源代码

pub fn new_current_thread() -> Builder

返回一个选择了当前线程调度器的新构建器。

可以在返回值上链式调用各配置方法。

要在所得到的运行时上派生非 Send 任务,需要将其与 LocalSet 组合使用,或者调用 build_local 来创建 LocalRuntime

源代码

pub fn enable_all(&mut self) -> &mut Self

同时启用 I/O 和时间驱动。

这是单独调用 enable_ioenable_time 的简写。如果未来 Tokio 中添加了其他组件, enable_all 也会包括这些未来的组件。

§示例
use tokio::runtime;

let rt = runtime::Builder::new_multi_thread()
    .enable_all()
    .build()
    .unwrap();
源代码

pub fn worker_threads(&mut self, val: usize) -> &mut Self

设置 Runtime 将使用的工作线程数。

该值可以是大于 0 的任何数字,不过建议保持一个较小的值。

这会覆盖从环境变量 TOKIO_WORKER_THREADS 读取的值。

§默认值

默认值是系统可用的 CPU 核心数。

使用 current_thread 运行时,此方法无效。

§示例
§具有 4 个线程的多线程运行时
use tokio::runtime;

// 这将派生一个具有 4 个工作线程的工作窃取型运行时。
let rt = runtime::Builder::new_multi_thread()
    .worker_threads(4)
    .build()
    .unwrap();

rt.spawn(async move {});
§当前线程运行时(仅通过 Runtime::block_on 在当前线程上运行)
use tokio::runtime;

// 创建一个必须通过调用
// `Runtime::block_on` 来驱动的运行时。
let rt = runtime::Builder::new_current_thread()
    .build()
    .unwrap();

// 这将在当前线程上运行运行时和 future
rt.block_on(async move {});
§恐慌

如果 val 不大于 0,则会发生 panic。

源代码

pub fn max_blocking_threads(&mut self, val: usize) -> &mut Self

指定运行时派生的额外线程的上限。

这些线程用于阻塞操作,例如通过 spawn_blocking 派生的任务,包括但不限于:

worker_threads 不同,这些线程并非始终处于活动状态, 如果空闲时间过长会退出。可以使用 thread_keep_alive 更改该超时时长。

建议不要将该上限设置得过低,以避免在需要 spawn_blocking 的操作上发生挂起。

默认值是 512。

§队列行为

当提交一个阻塞任务时,它会被插入一个队列中。如果有空闲线程,则会通知其中一个线程来运行该任务。否则, 如果尚未达到本方法设置的阈值,则会派生一个新的线程。如果没有可用的空闲线程,并且也不再允许派生新线程, 那么该任务将一直留在队列中,直到某个繁忙的线程将其取出。需要注意的是,由于队列不施加任何背压, 因此它可能会无限增长。

§恐慌

如果 val 不大于 0,则会发生 panic。

§从 0.x 升级

在旧版本中,max_threads 同时限制阻塞线程和工作线程的数量, 但当前的 max_blocking_threads 不再将异步工作线程计入该数量中。

源代码

pub fn thread_name(&mut self, val: impl Into<String>) -> &mut Self

设置 Runtime 线程池所派生线程的名称。

默认名称为 “tokio-rt-worker”。

§示例

let rt = runtime::Builder::new_multi_thread()
    .thread_name("my-pool")
    .build();
源代码

pub fn name(&mut self, val: impl Into<String>) -> &mut Self

设置运行时的名称。

§示例

let rt = runtime::Builder::new_multi_thread()
    .name("my-runtime")
    .build();
§恐慌

如果将空值作为参数传入,此函数将发生 panic。

源代码

pub fn thread_name_fn<F>(&mut self, f: F) -> &mut Self
where F: Fn() -> String + Send + Sync + 'static,

设置一个用于生成 Runtime 线程池所派生线程名称的函数。

默认的名称函数是 || "tokio-rt-worker".into()

§示例
let rt = runtime::Builder::new_multi_thread()
    .thread_name_fn(|| {
       static ATOMIC_ID: AtomicUsize = AtomicUsize::new(0);
       let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst);
       format!("my-pool-{}", id)
    })
    .build();
源代码

pub fn thread_stack_size(&mut self, val: usize) -> &mut Self

设置工作线程的栈大小(以字节为单位)。

如果平台指定了最小栈大小,实际的栈大小可能大于此值。

所派生线程的默认栈大小为 2 MiB,但此特定的栈大小将来可能会发生变化。

§示例

let rt = runtime::Builder::new_multi_thread()
    .thread_stack_size(32 * 1024)
    .build();
源代码

pub fn on_thread_start<F>(&mut self, f: F) -> &mut Self
where F: Fn() + Send + Sync + 'static,

在每个线程启动之后、开始工作之前执行函数 f

此回调用于簿记和监控场景。

§示例
let runtime = runtime::Builder::new_multi_thread()
    .on_thread_start(|| {
        println!("thread started");
    })
    .build();
源代码

pub fn on_thread_stop<F>(&mut self, f: F) -> &mut Self
where F: Fn() + Send + Sync + 'static,

在每个线程停止之前执行函数 f

此回调用于簿记和监控场景。

§示例
{
let runtime = runtime::Builder::new_multi_thread()
    .on_thread_stop(|| {
        println!("thread stopping");
    })
    .build();
源代码

pub fn on_thread_park<F>(&mut self, f: F) -> &mut Self
where F: Fn() + Send + Sync + 'static,

在线程即将被 park(变为空闲)之前执行函数 ff 在 Tokio 上下文中被调用,因此可以调用 tokio::spawn 等函数,这可能会导致该线程被立即 unpark。

可以用于仅在执行器空闲时启动工作,或用于簿记和监控目的。

注意:每个运行时只能有一个 park 回调;多次调用此函数将替换最后定义的回调, 而不是叠加。

§示例
§多线程执行器
let once = AtomicBool::new(true);
let barrier = Arc::new(Barrier::new(2));

let runtime = runtime::Builder::new_multi_thread()
    .worker_threads(1)
    .on_thread_park({
        let barrier = barrier.clone();
        move || {
            let barrier = barrier.clone();
            if once.swap(false, Ordering::Relaxed) {
                tokio::spawn(async move { barrier.wait().await; });
           }
        }
    })
    .build()
    .unwrap();

runtime.block_on(async {
   barrier.wait().await;
})
§当前线程执行器
let once = AtomicBool::new(true);
let barrier = Arc::new(Barrier::new(2));

let runtime = runtime::Builder::new_current_thread()
    .on_thread_park({
        let barrier = barrier.clone();
        move || {
            let barrier = barrier.clone();
            if once.swap(false, Ordering::Relaxed) {
                tokio::spawn(async move { barrier.wait().await; });
           }
        }
    })
    .build()
    .unwrap();

runtime.block_on(async {
   barrier.wait().await;
})
源代码

pub fn on_thread_unpark<F>(&mut self, f: F) -> &mut Self
where F: Fn() + Send + Sync + 'static,

在线程 unpark(开始执行任务)之后立即执行函数 f

此回调用于簿记和监控场景;需要注意的是,当应用程序允许一个或多个运行时线程 进入空闲状态时,此回调中的工作会增加延迟。

注意:每个运行时只能有一个 unpark 回调;多次调用此函数将替换最后定义的回调, 而不是叠加。

§示例
let runtime = runtime::Builder::new_multi_thread()
    .on_thread_unpark(|| {
        println!("thread unparking");
    })
    .build();

runtime.unwrap().block_on(async {
   tokio::task::yield_now().await;
   println!("Hello from Tokio!");
})
源代码

pub fn build(&mut self) -> Result<Runtime>

根据配置创建 Runtime

返回的 Runtime 实例已准备好派生任务。

§示例
use tokio::runtime::Builder;

let rt  = Builder::new_multi_thread().build().unwrap();

rt.block_on(async {
    println!("Hello from the Tokio runtime");
});
源代码

pub fn build_local(&mut self, options: LocalOptions) -> Result<LocalRuntime>

根据配置创建 LocalRuntime

返回的 LocalRuntime 实例已准备好派生任务。

§恐慌

如果运行时是使用 new_multi_thread() 配置的,则会发生 panic。

§示例
use tokio::runtime::{Builder, LocalOptions};

let rt = Builder::new_current_thread()
    .build_local(LocalOptions::default())
    .unwrap();

rt.spawn_local(async {
    println!("Hello from the Tokio runtime");
});
源代码

pub fn thread_keep_alive(&mut self, duration: Duration) -> &mut Self

设置阻塞池中线程的自定义超时时间。

默认情况下,线程的超时时间被设置为 10 秒。可以使用 .thread_keep_alive() 覆盖此设置。

§示例
let rt = runtime::Builder::new_multi_thread()
    .thread_keep_alive(Duration::from_millis(100))
    .build();
源代码

pub fn global_queue_interval(&mut self, val: u32) -> &mut Self

设置调度器在多少个调度 tick 之后轮询全局任务队列。

一个调度“tick”大致对应于对任务的 poll 调用一次。

对于当前线程调度器,默认的全局队列间隔为 31。有关多线程调度器的默认行为,请参阅 模块文档

调度器有一个本地队列用于存放已认领的任务,还有一个全局队列用于存放新进入的任务。 将间隔设置得更小可以提高调度器的公平性,但代价是会增加同步开销。这有利于优先开始新工作, 特别是当任务经常让出执行权而不是完成或等待更多 I/O 时。将间隔设置为 1 将优先处理全局队列, 只有当全局队列为空时才会执行本地队列中的任务。相反,较大的值则会优先处理现有工作, 当大多数任务能很快完成轮询时,这是一个不错的选择。

§恐慌

如果将 0 作为参数传入,此函数将发生 panic。

§示例
let rt = runtime::Builder::new_multi_thread()
    .global_queue_interval(31)
    .build();
源代码

pub fn event_interval(&mut self, val: u32) -> &mut Self

设置调度器在多少个调度 tick 之后轮询外部事件(定时器、I/O 等)。

一个调度“tick”大致对应于对任务的 poll 调用一次。

默认情况下,所有调度器类型的事件间隔为 61

设置事件间隔决定了传递这些外部事件(它们可能会唤醒其他任务)的有效“优先级”, 相对于执行当前已就绪的任务。当任务经常在轮询中花费较长时间或不经常让出执行权时, 较小的值很有用,否则可能会导致在处理 I/O 事件时出现过长的延迟。 相反,拾取新事件需要额外的同步和系统调用开销,所以如果任务通常能很快完成轮询, 那么使用较大的事件间隔可以将这种开销降至最低,同时仍能保持调度器对事件的响应能力。

§恐慌

如果将 0 作为参数传入,此函数将发生 panic。

§示例
let rt = runtime::Builder::new_multi_thread()
    .event_interval(31)
    .build();
源代码§

impl Builder

源代码

pub fn enable_io(&mut self) -> &mut Self

启用 I/O 驱动。

启用后即可在运行时上使用 net、process、signal 以及某些 I/O 类型。

§示例
use tokio::runtime;

let rt = runtime::Builder::new_multi_thread()
    .enable_io()
    .build()
    .unwrap();
源代码

pub fn max_io_events_per_tick(&mut self, capacity: usize) -> &mut Self

启用 I/O 驱动,并配置每个 tick 处理的最大事件数。

§示例
use tokio::runtime;

let rt = runtime::Builder::new_current_thread()
    .enable_io()
    .max_io_events_per_tick(1024)
    .build()
    .unwrap();
源代码§

impl Builder

源代码

pub fn enable_time(&mut self) -> &mut Self

启用时间驱动。

启用后即可在运行时上使用 tokio::time

§示例
use tokio::runtime;

let rt = runtime::Builder::new_multi_thread()
    .enable_time()
    .build()
    .unwrap();

trait 实现§

源代码§

impl Debug for Builder

源代码§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result

使用给定的格式化器格式化此值。 更多信息

自动 trait 实现§

blanket 实现§

源代码§

impl<T> Any for T
where T: 'static + ?Sized,

源代码§

fn type_id(&self) -> TypeId

Gets the TypeId of self. 更多信息
源代码§

impl<T> Borrow<T> for T
where T: ?Sized,

源代码§

fn borrow(&self) -> &T

Immutably borrows from an owned value. 更多信息
源代码§

impl<T> BorrowMut<T> for T
where T: ?Sized,

源代码§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. 更多信息
源代码§

impl<T> From<T> for T

源代码§

fn from(t: T) -> T

原样返回参数。

源代码§

impl<T, U> Into<U> for T
where U: From<T>,

源代码§

fn into(self) -> U

调用 U::from(self)

也就是说,此转换是 From<T> for U 实现选择执行的操作。

源代码§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

源代码§

type Error = Infallible

转换出错时返回的类型。
源代码§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

执行转换。
源代码§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

源代码§

type Error = <U as TryFrom<T>>::Error

转换出错时返回的类型。
源代码§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

执行转换。