pub struct Handle { /* 私有字段 */ }展开描述
运行时句柄。
该句柄内部是引用计数的,可以自由克隆。可以使用 Runtime::handle 方法获取句柄。
实现§
源代码§impl Handle
impl Handle
源代码pub fn enter(&self) -> EnterGuard<'_>
pub fn enter(&self) -> EnterGuard<'_>
进入运行时上下文。这允许你构造在创建时必须有可用的执行器的类型,例如 Sleep 或 TcpStream。它还允许你调用 tokio::spawn 和 Handle::current 等方法而不会发生 panic。
§恐慌
当多次调用 Handle::enter 时,返回的 guard 必须以获取它们的相反顺序 drop。否则将导致 panic 和可能的内存泄漏。
§示例
use tokio::runtime::Runtime;
let rt = Runtime::new().unwrap();
let _guard = rt.enter();
tokio::spawn(async {
println!("Hello world!");
});不要执行以下操作,这显示了一个会导致 panic 和可能的内存泄漏的场景。
use tokio::runtime::Runtime;
let rt1 = Runtime::new().unwrap();
let rt2 = Runtime::new().unwrap();
let enter1 = rt1.enter();
let enter2 = rt2.enter();
drop(enter1);
drop(enter2);源代码pub fn current() -> Self
pub fn current() -> Self
返回当前正在运行的 Runtime 的 Handle 视图。
§恐慌
如果在 Tokio 运行时的上下文之外调用此函数,则会发生 panic。这意味着你必须在由运行时运行的某个线程上调用它,或者从具有活动 EnterGuard 的线程调用。例如,从 std::thread::spawn 创建的线程中调用会导致 panic,除非该线程具有活动的 EnterGuard。
§示例
这可用于从在该运行时上运行的 async 块或函数获取周围运行时的句柄。
use tokio::runtime::Handle;
// Inside an async block or function.
let handle = Handle::current();
handle.spawn(async {
println!("now running in the existing Runtime");
});
thread::spawn(move || {
// Notice that the handle is created outside of this thread and then moved in
handle.spawn(async { /* ... */ });
// This next line would cause a panic because we haven't entered the runtime
// and created an EnterGuard
// let handle2 = Handle::current(); // panic
// So we create a guard here with Handle::enter();
let _guard = handle.enter();
// Now we can call Handle::current();
let handle2 = Handle::current();
});源代码pub fn try_current() -> Result<Self, TryCurrentError>
pub fn try_current() -> Result<Self, TryCurrentError>
返回当前正在运行的 Runtime 的 Handle 视图
如果尚未启动 Runtime,则返回错误
与 current 不同,此函数从不发生 panic
源代码pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output> ⓘ
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output> ⓘ
将 future 派生到 Tokio 运行时。
这会将给定的 future 派生到运行时的执行器上,通常是线程池。然后由该线程池负责轮询该 future 直到其完成。
当调用 spawn 时,提供的 future 将立即开始在后台运行,即使你未 await 返回的 JoinHandle 也是如此(假设运行时正在运行)。
有关更多详细信息,请参阅 模块级 文档。
§示例
use tokio::runtime::Runtime;
// 创建运行时
let rt = Runtime::new().unwrap();
// 从此运行时获取一个句柄
let handle = rt.handle();
// Spawn a future onto the runtime using the handle
handle.spawn(async {
println!("now running on a worker thread");
});源代码pub 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;
// 创建运行时
let rt = Runtime::new().unwrap();
// 从此运行时获取一个句柄
let handle = rt.handle();
// Spawn a blocking function onto the runtime using the handle
handle.spawn_blocking(|| {
println!("now running on a worker thread");
});源代码pub fn block_on<F: Future>(&self, future: F) -> F::Output
pub fn block_on<F: Future>(&self, future: F) -> F::Output
在此 Handle 关联的 Runtime 上将一个 future 运行到完成。
这会在当前线程上运行给定的 future,阻塞直到它完成,并产生其解析结果。future 内部生成的任何任务或计时器都将在运行时上执行。
当在 current_thread 运行时上使用时,只有 Runtime::block_on 方法可以驱动 IO 和计时器驱动,但 Handle::block_on 方法不能驱动它们。这意味着,在 current_thread 运行时上使用此方法时,除非有另一个线程正在同一运行时上调用 Runtime::block_on,否则任何依赖于 IO 或计时器的功能都无法工作。
§If the runtime has been shut down
如果 Handle 关联的 Runtime 已关闭(通过 Runtime::shutdown_background、Runtime::shutdown_timeout 或 drop 它),然后使用 Handle::block_on 可能会返回错误或发生 panic。具体来说,IO 资源将返回错误,计时器将发生 panic。独立于运行时的 future 将正常运行。
§恐慌
如果满足以下任何条件,此函数将发生 panic:
- The provided future panics.
- It is called from within an asynchronous context, such as inside
Runtime::block_on,Handle::block_on, or from a function annotated withtokio::main. - A timer future is executed on a runtime that has been shut down.
§示例
use tokio::runtime::Runtime;
// 创建运行时
let rt = Runtime::new().unwrap();
// 从此运行时获取一个句柄
let handle = rt.handle();
// 执行 future,阻塞当前线程直到完成
handle.block_on(async {
println!("hello");
});或使用 Handle::current:
use tokio::runtime::Handle;
#[tokio::main]
async fn main () {
let handle = Handle::current();
std::thread::spawn(move || {
// Using Handle::block_on to run async code in the new thread.
handle.block_on(async {
println!("hello");
});
});
}Handle::block_on 可以与 task::block_in_place 结合使用,以重新进入多线程调度器运行时的异步上下文:
use tokio::task;
use tokio::runtime::Handle;
task::block_in_place(move || {
Handle::current().block_on(async move {
// do something async
});
});源代码pub fn runtime_flavor(&self) -> RuntimeFlavor
pub fn runtime_flavor(&self) -> RuntimeFlavor
返回当前 Runtime 的风格。
§示例
use tokio::runtime::{Handle, RuntimeFlavor};
#[tokio::main(flavor = "current_thread")]
async fn main() {
assert_eq!(RuntimeFlavor::CurrentThread, Handle::current().runtime_flavor());
}use tokio::runtime::{Handle, RuntimeFlavor};
#[tokio::main(flavor = "multi_thread", worker_threads = 4)]
async fn main() {
assert_eq!(RuntimeFlavor::MultiThread, Handle::current().runtime_flavor());
}源代码pub fn name(&self) -> Option<&str>
pub fn name(&self) -> Option<&str>
返回当前 Runtime 的名称。
§示例
use tokio::runtime::Handle;
#[tokio::main(flavor = "current_thread", name = "my-runtime")]
async fn main() {
println!("Current runtime name: {}", Handle::current().name().unwrap());
}源代码pub fn metrics(&self) -> RuntimeMetrics
pub fn metrics(&self) -> RuntimeMetrics
返回一个视图,可用于获取运行时性能的相关信息。