Tokio 無疑是 Rust 世界中最優(yōu)秀的異步Runtime實現(xiàn)。非阻塞的特性帶來了優(yōu)異的性能,但是在實際的開發(fā)中我們往往需要在某些情況下阻塞任務(wù)來實現(xiàn)某些功能。
我們看看下面的例子
fn main(){
let max_task = 1;
let rt = runtime::new_multi_thread()
.worker_threads(max_task)
.build()
.unwrap();
rt.block_on(async {
println!("tokio_multi_thread ");
for i in 0..100 {
println!("run {}", i);
tokio::spawn(async move {
println!("spawn {}", i);
thread::from_secs(2));
});
}
});
}
我們期待的運行結(jié)構(gòu)是通過異步任務(wù)打印出99個 “spawn i",但實際輸出的結(jié)果大概這樣
tokio_multi_thread
run 0
run 1
run 2
.......
run 16
spawn 0
run 17
......
run 99
spawn 1
spawn 2
......
spawn 29
......
spawn 58
spawn 59
59執(zhí)行完后面就沒有輸出了,如果把max_task設(shè)置為2,情況會好一點,但是也沒有執(zhí)行完所有的異步操作,也就是說在資源不足的情況下,Tokio會拋棄某些任務(wù),這不符合我們的預(yù)期。那么能不能再達(dá)到了某一閥值的情況下阻塞一下,不再給Tokio新的任務(wù)呢。這有點類似線程池,當(dāng)達(dá)達(dá)最大線程數(shù)的時候阻塞后面的任務(wù)待有釋放的線程后再繼續(xù)。我們看看下面的代碼。
fn main(){
let max_task = 2;
let rt = runtime::new_multi_thread()
.worker_threads(max_task)
.enable_time()
.build()
.unwrap();
let mut set = JoinSet::new();
rt.block_on(async {
for i in 0..100 {
println!("run {}", i);
while set.len() >= max_task {
set.join_next().await;
}
set.spawn(async move {
sleep().await;
println!("spawn {}", i);
});
}
while set.len() > 0 {
set.join_next().await;
}
});
}
我們使用JoinSet來管理派生出來的任務(wù)。set.join_next().await; 保證至少一個任務(wù)被執(zhí)行完成。結(jié)合set的len,我們可以在任務(wù)達(dá)到上限時阻塞任務(wù)派生。當(dāng)循環(huán)結(jié)束,可能還有未完成的任務(wù),所以只要set.len()大于0就等待任務(wù)結(jié)束。輸出大概長這樣
running 1 test
tokio_multi_thread
run 0
run 1
spawn 0
run 2
spawn 1
......
run 31
spawn 30
run 32
spawn 31
run 33
......
run 96
spawn 95
run 97
spawn 96
run 98
spawn 97
run 99
spawn 98
spawn 99
符合預(yù)期,代碼不多,有興趣的同學(xué)可以動手嘗試一下。審核編輯 :李倩
-
線程池
+關(guān)注
關(guān)注
0文章
56瀏覽量
6828 -
非阻塞
+關(guān)注
關(guān)注
0文章
12瀏覽量
2164 -
Rust
+關(guān)注
關(guān)注
1文章
228瀏覽量
6542 -
Tokio
+關(guān)注
關(guān)注
0文章
12瀏覽量
50
原文標(biāo)題:文盤Rust -- 用Tokio實現(xiàn)簡易任務(wù)池
文章出處:【微信號:Rust語言中文社區(qū),微信公眾號:Rust語言中文社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論