能否在Tokio当前线程内派生当前线程的任务?附current_thread executor代码
问题解答
问题1:能否在Tokio的当前线程内部,于该当前线程上派生任务?
当然可以!但有两个关键前提:
- 你必须确保当前线程已经绑定了Tokio执行器的上下文(比如正在
CurrentThread执行器的任务中运行); - 对于
current_thread这种单线程执行器,派生的任务会在同一个线程上调度,但要避免阻塞执行器线程(比如用thread::sleep这种同步阻塞操作会让执行器无法处理新任务)。
问题2:如何在current_thread执行器的foo函数内派生任务?
你的代码里有个核心问题:tokio::spawn在Tokio 0.1版本中默认会将任务提交到全局多线程执行器,而不是你当前使用的current_thread单线程执行器。所以要让任务在同一个current_thread上运行,需要使用该执行器自身的句柄(Handle)来派生任务。
修改后的代码示例
extern crate futures; // version 0.1 extern crate tokio; use futures::future::lazy; use std::{time, thread}; use tokio::executor::current_thread::{CurrentThread, Handle}; use tokio::timer::Delay; // 用异步延迟替代同步sleep,避免阻塞执行器 fn foo(handle: &Handle) { // 使用current_thread的Handle来派生任务,确保任务在同一个线程执行 handle.spawn(lazy(|| { println!("In foo!"); Ok(()) })).unwrap(); // 处理spawn可能的错误 } fn main() { let mut current_thread = CurrentThread::new(); // 获取current_thread的句柄,用于在任务内部派生新任务 let handle = current_thread.handle(); current_thread.spawn(lazy(move || { loop { println!("In spawn!"); foo(&handle); // 用异步Delay替代thread::sleep,避免阻塞执行器线程 Delay::new(time::Instant::now() + time::Duration::from_secs(1)) .wait() .unwrap(); } Ok(()) })).unwrap(); // 启动执行器,直到所有任务完成(这里是无限循环,所以会一直运行) current_thread.run().unwrap(); }
关键修改点说明
- 使用
CurrentThread::handle()获取执行器句柄:通过这个句柄派生的任务会直接提交到当前的current_thread执行器,确保在同一个线程上调度; - 替换
thread::sleep为tokio::timer::Delay:同步sleep会阻塞单线程执行器,导致派生的foo任务无法被及时处理。异步延迟能让执行器在等待期间调度其他任务; - 错误处理:添加
unwrap()处理spawn和wait可能返回的错误(实际项目中建议更优雅的错误处理)。
内容的提问来源于stack exchange,提问作者user1413793
相关产品推荐
相关产品推荐

