pub struct Handle { /* private fields */ }展开描述
运行时的句柄。
此句柄
内部使用引用计数,
可以自由克隆。
可以使用
Runtime::handle
方法
获取一个句柄。
实现§
Source§impl Handle
impl Handle
Sourcepub fn enter(&self) -> EnterGuard<'_>
pub fn enter(&self) -> EnterGuard<'_>
进入运行时上下文。这允许你构造创建时必须有可用执行器的类型,例如 Sleep 或
TcpStream。它还允许你调用 tokio::spawn 和 Handle::current 等方法而不会 panic。
§Panics
多次调用 Handle::enter 时,返回的守卫必须按与获取相反的顺序 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);Sourcepub fn current() -> Self
pub fn current() -> Self
返回当前正在运行的 Runtime 的 Handle 视图。
§Panics
如果在 Tokio 运行时的上下文之外调用此方法会 panic。也就是说,你必须在由运行时运行的某个线程上调用此方法,或者在持有活跃 EnterGuard 的线程上调用。例如,在由 std::thread::spawn 创建的线程内调用此方法会导致 panic,除非该线程持有活跃的 EnterGuard。
§示例
此方法可用于从该运行时上运行的异步块或异步函数中获取其所属运行时的句柄。
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();
});Sourcepub fn try_current() -> Result<Self, TryCurrentError>
pub fn try_current() -> Result<Self, TryCurrentError>
返回当前正在运行的 Runtime 的 Handle 视图
如果没有启动 Runtime,则返回错误
与 current 不同,此方法永远不会 panic
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();
// Get a handle from this runtime
let handle = rt.handle();
// Spawn a future onto the runtime using the handle
handle.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();
// Get a handle from this runtime
let handle = rt.handle();
// Spawn a blocking function onto the runtime using the handle
handle.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
在该 Handle 所关联的 Runtime 上运行一个 future 直到完成。
此方法在当前线程上运行给定的 future,阻塞直到其完成,并产出其解析后的结果。future 在内部派生的任何任务或定时器都将在运行时上执行。
当在 current_thread 运行时上使用时,只有 Runtime::block_on 方法能够驱动 IO 和 timer driver,而 Handle::block_on 方法不能驱动它们。这意味着,在 current_thread 运行时上使用此方法时,任何依赖 IO 或 timer 的功能都无法工作,除非同一运行时上有另一个线程正在调用 Runtime::block_on。
§If the runtime has been shut down
如果该 Handle 所关联的 Runtime 已经被关闭(通过 Runtime::shutdown_background、Runtime::shutdown_timeout 或 drop 它),并且使用了 Handle::block_on,它可能会返回错误或发生 panic。具体而言,IO 资源将返回错误,timer 将 panic。运行时无关的 future 将正常运行。
§Panics
如果满足以下任何条件,此函数将发生 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;
// Create the runtime
let rt = Runtime::new().unwrap();
// Get a handle from this runtime
let handle = rt.handle();
// Execute the future, blocking the current thread until completion
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
});
});Sourcepub 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());
}Sourcepub 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());
}Sourcepub fn metrics(&self) -> RuntimeMetrics
pub fn metrics(&self) -> RuntimeMetrics
返回一个视图,可用于获取运行时运行状况的相关信息。