pub struct Runtime { /* private fields */ }展开描述
Tokio 运行时。
运行时 提供 IO driver、 任务调度器、 定时器 和阻塞池, 用于运行异步任务所必需。
可以使用 new 或 Builder 创建 Runtime 实例。
不过,大多数用户会在其入口点使用 #[tokio::main] 注解。
更多详细信息请参见模块级文档。
§Shutdown
关闭运行时
是通过丢弃该值来完成的,
或调用
shutdown_background
或
shutdown_timeout。
通过
Runtime::spawn
派生的任务
会一直运行直到它们让出。
然后它们被丢弃。
它们不保证
会运行到完成,
但如果它们
在完成前不让出,
则可能
会运行到完成。
通过
Runtime::spawn_blocking
派生的阻塞函数
会一直运行直到它们返回。
发起关闭的线程
会阻塞直到
所有派生工作停止。
这可能需要
不确定的时间。
Drop 实现
会永远等待这一点。
如果不想
永远等待,
可以使用
shutdown_background
和
shutdown_timeout
方法。
当达到超时时,
未及时停止的派生工作
以及运行它们的线程
会被泄露。
工作将继续运行,
直到满足某个
停止条件,
但
发起关闭的线程
会被解除阻塞。
运行时一旦被丢弃, 绑定到它的 所有未完成的 IO 资源 将不再工作。 调用它们的任何方法 都将导致错误。
§Sharing
有几种方法 可以建立 对 Tokio 运行时的共享访问:
使用
Arc<Runtime>
或
Handle
允许你
使用运行时
执行各种操作,
例如
派生新任务
或进入
运行时上下文。
两种类型
都可以被克隆
以创建
允许访问
同一运行时的新句柄。
通过将克隆体
传递到
不同的任务或线程,
你将能够
从这些任务或线程
访问运行时。
Arc<Runtime>
和
Handle
的区别
在于
Arc<Runtime>
会阻止运行时关闭,
而
Handle
不会
阻止。
这是因为运行时的关闭
发生在
Runtime
对象的
析构函数
运行时。
对
shutdown_background
和
shutdown_timeout
的调用
需要对 Runtime 类型的
独占所有权。
当使用
Arc<Runtime> 时,
可以通过
Arc::try_unwrap
实现,
前提是
只剩一个
强计数引用。
运行时上下文
通过
Runtime::enter
或
Handle::enter
方法进入,
这些方法
使用线程局部变量
来存储当前运行时。
只要
你在运行时上下文内,
诸如
tokio::spawn
的方法
将使用
你所在上下文对应的运行时。
实现§
Source§impl Runtime
impl Runtime
Sourcepub fn new() -> Result<Runtime>
pub fn new() -> Result<Runtime>
使用默认配置值创建一个新的运行时实例。
这将初始化多线程调度器、I/O driver 和 time driver。
大多数应用程序不需要直接调用此函数。它们将使用 #[tokio::main] 属性。当需要更复杂的配置时,可以使用运行时 builder。
更多详细信息请参见模块级文档。
§示例
使用默认配置值创建一个新的 Runtime。
use tokio::runtime::Runtime;
let rt = Runtime::new()
.unwrap();
// Use the runtime...Sourcepub fn handle(&self) -> &Handle
pub fn handle(&self) -> &Handle
返回运行时 spawner 的句柄。
返回的句柄可用于派生在此运行时上运行的任务,并且可以克隆,以便将 Handle 移动到其他线程。
在 current_thread 运行时的句柄上调用 Handle::block_on 是容易出错的。
更多细节请参考 Handle::block_on 的文档。
§示例
use tokio::runtime::Runtime;
let rt = Runtime::new()
.unwrap();
let handle = rt.handle();
// Use the handle...Sourcepub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output> ⓘ
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output> ⓘ
将 future 派生到 Tokio 运行时上。
此方法将给定的 future 派生到运行时的执行器(通常是线程池)上。然后由线程池负责 poll future 直到其完成。
给定的 future 在调用 spawn 后会立即开始在后台运行,即使你没有 await 返回的 JoinHandle(前提是运行时正在运行)。
更多详细信息请参见模块级文档。
§示例
use tokio::runtime::Runtime;
// Create the runtime
let rt = Runtime::new().unwrap();
// Spawn a future onto the runtime
rt.spawn(async {
println!("now running on a worker thread");
});Sourcepub fn spawn_blocking<F, R>(&self, func: F) -> JoinHandle<R> ⓘ
pub fn spawn_blocking<F, R>(&self, func: F) -> JoinHandle<R> ⓘ
在专用于阻塞操作的执行器上运行提供的函数。
§示例
use tokio::runtime::Runtime;
// Create the runtime
let rt = Runtime::new().unwrap();
// Spawn a blocking function onto the runtime
rt.spawn_blocking(|| {
println!("now running on a worker thread");
});Sourcepub fn block_on<F: Future>(&self, future: F) -> F::Output
pub fn block_on<F: Future>(&self, future: F) -> F::Output
在 Tokio 运行时上运行一个 future 直到完成。这是运行时的入口点。
此方法在当前线程上运行给定的 future,阻塞直到其完成,并产出其解析后的结果。future 在内部派生的任何任务或定时器都将在运行时上执行。
§Non-worker future
请注意,此函数所需的 future 不会作为 worker 运行。这里的预期是 future 内部会派生其他任务。在提供的 future 中 await 其他 future,其性能不会像作为 worker 派生的任务那样快。
§Multi thread scheduler
使用多线程调度器时,future 可以在整体运行时的 io driver 和 timer 上下文中运行。
任何已派生的任务将在 block_on 返回后继续运行.
§Current thread scheduler
启用 current thread scheduler 时,block_on 可以从多个线程并发调用。第一次调用将获得 io 和 timer driver 的所有权。这意味着不拥有 driver 的其他线程将挂接到该 driver 上。当第一次 block_on 完成时,其他线程将能够"窃取"该 driver 以允许它们的 future 继续执行。
任何已派生的任务将在 block_on 返回后挂起。再次调用 block_on 将恢复之前已派生的任务。
§Panics
如果提供的 future 发生 panic,或在异步执行上下文中调用,则此函数将 panic。
§示例
use tokio::runtime::Runtime;
// Create the runtime
let rt = Runtime::new().unwrap();
// Execute the future, blocking the current thread until completion
rt.block_on(async {
println!("hello");
});Sourcepub fn enter(&self) -> EnterGuard<'_>
pub fn enter(&self) -> EnterGuard<'_>
进入运行时上下文。
这允许你构造创建时必须有可用执行器的类型,例如 Sleep 或 TcpStream。它还允许你调用 tokio::spawn 等方法。
§Example
use tokio::runtime::Runtime;
use tokio::task::JoinHandle;
fn function_that_spawns(msg: String) -> JoinHandle<()> {
// Had we not used `rt.enter` below, this would panic.
tokio::spawn(async move {
println!("{}", msg);
})
}
fn main() {
let rt = Runtime::new().unwrap();
let s = "Hello World!".to_string();
// By entering the context, we tie `tokio::spawn` to this executor.
let _guard = rt.enter();
let handle = function_that_spawns(s);
// Wait for the task before we end the test.
rt.block_on(handle).unwrap();
}Sourcepub fn shutdown_timeout(self, duration: Duration)
pub fn shutdown_timeout(self, duration: Duration)
关闭运行时,最多等待 duration 时间让所有已派生的工作停止。
更多详细信息请参见 结构体级文档。
§示例
use tokio::runtime::Runtime;
use tokio::task;
use std::thread;
use std::time::Duration;
fn main() {
let runtime = Runtime::new().unwrap();
runtime.block_on(async move {
task::spawn_blocking(move || {
thread::sleep(Duration::from_secs(10_000));
});
});
runtime.shutdown_timeout(Duration::from_millis(100));
}Sourcepub fn shutdown_background(self)
pub fn shutdown_background(self)
关闭运行时,不等待任何已派生的工作停止。
如果你希望从另一个运行时内部 drop 一个运行时,这非常有用。通常情况下,drop 一个运行时会无限期阻塞,直到已派生的阻塞任务完成,这在异步上下文中通常是不允许的。调用 shutdown_background() 可以从此类上下文中 drop 该运行时。
但请注意,由于我们不会等待任何阻塞任务完成,这可能导致资源泄漏(任何阻塞任务仍在运行,直到它们返回)。
更多详细信息请参见 结构体级文档。
此函数等效于调用 shutdown_timeout(Duration::from_nanos(0))。
use tokio::runtime::Runtime;
fn main() {
let runtime = Runtime::new().unwrap();
runtime.block_on(async move {
let inner_runtime = Runtime::new().unwrap();
// ...
inner_runtime.shutdown_background();
});
}Sourcepub fn metrics(&self) -> RuntimeMetrics
pub fn metrics(&self) -> RuntimeMetrics
返回一个视图,可用于获取运行时运行状况的相关信息。