找回密码
 会员注册
查看: 42|回复: 0

文盘Rust--用Tokio实现简易任务池

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
64077
发表于 2024-9-26 02:41:26 | 显示全部楼层 |阅读模式
Tokio无疑是Rust世界中最优秀的异步Runtime实现。非阻塞的特性带来了优异的性能,但是在实际的开发中我们往往需要在某些情况下阻塞任务来实现某些功能。我们看看下面的例子fnmain(){letmax_task=1;letrt=runtime::Builder::new_multi_thread().worker_threads(max_task).build().unwrap();rt.block_on(async{println!("tokio_multi_thread");foriin0..100{println!("run{}",i);tokio::spawn(asyncmove{println!("spawn{}",i);thread::sleep(Duration::from_secs(2));});}});}我们期待的运行结构是通过异步任务打印出99个“spawni",但实际输出的结果大概这样tokio_multi_threadrun0run1run2.......run16spawn0run17......run99spawn1spawn2......spawn29......spawn58spawn5959执行完后面就没有输出了,如果把max_task设置为2,情况会好一点,但是也没有执行完所有的异步操作,也就是说在资源不足的情况下,Tokio会抛弃某些任务,这不符合我们的预期。那么能不能再达到了某一阀值的情况下阻塞一下,不再给Tokio新的任务呢。这有点类似线程池,当达达最大线程数的时候阻塞后面的任务待有释放的线程后再继续。我们看看下面的代码。fnmain(){letmax_task=2;letrt=runtime::Builder::new_multi_thread().worker_threads(max_task).enable_time().build().unwrap();letmutset=JoinSet::new();rt.block_on(async{foriin0..100{println!("run{}",i);whileset.len()>=max_task{set.join_next().await;}set.spawn(asyncmove{sleep().await;println!("spawn{}",i);});}whileset.len()>0{set.join_next().await;}});}我们使用JoinSet来管理派生出来的任务。set.join_next().await;保证至少一个任务被执行完成。结合set的len,我们可以在任务达到上限时阻塞任务派生。当循环结束,可能还有未完成的任务,所以只要set.len()大于0就等待任务结束。输出大概长这样running1testtokio_multi_threadrun0run1spawn0run2spawn1......run31spawn30run32spawn31run33......run96spawn95run97spawn96run98spawn97run99spawn98spawn99符合预期,代码不多,有兴趣的同学可以动手尝试一下。-end-
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 11:18 , Processed in 0.325044 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表