文盤Rust -- 用Tokio實現簡易任務池

来源:https://www.cnblogs.com/jingdongkeji/archive/2023/04/14/17317697.html
-Advertisement-
Play Games

Tokio 無疑是 Rust 世界中最優秀的非同步Runtime實現。非阻塞的特性帶來了優異的性能,但是在實際的開發中我們往往需要在某些情況下阻塞任務來實現某些功能。 ...


作者:京東科技 賈世聞

Tokio 無疑是 Rust 世界中最優秀的非同步Runtime實現。非阻塞的特性帶來了優異的性能,但是在實際的開發中我們往往需要在某些情況下阻塞任務來實現某些功能。

我們看看下麵的例子

fn main(){


        let max_task = 1;


        let rt = runtime::Builder::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::sleep(Duration::from_secs(2));


                });


            }


        });


    }

我們期待的運行結構是通過非同步任務列印出99個 “spawn i",但實際輸出的結果大概這樣

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執行完後面就沒有輸出了,如果把max_task設置為2,情況會好一點,但是也沒有執行完所有的非同步操作,也就是說在資源不足的情況下,Tokio會拋棄某些任務,這不符合我們的預期。那麼能不能再達到了某一閥值的情況下阻塞一下,不再給Tokio新的任務呢。這有點類似線程池,當達達最大線程數的時候阻塞後面的任務待有釋放的線程後再繼續。

我們看看下麵的代碼。

fn main(){


        let max_task = 2;


        let rt = runtime::Builder::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來管理派生出來的任務。set.join_next().await; 保證至少一個任務被執行完成。結合set的len,我們可以在任務達到上限時阻塞任務派生。當迴圈結束,可能還有未完成的任務,所以只要set.len()大於0就等待任務結束。

輸出大概長這樣

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

符合預期,代碼不多,有興趣的同學可以動手嘗試一下。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 是什麼 迴圈隊列, FIFO先進先出 怎麼用 初始化 //C11 deque<int> deq{1,2,3,4,5}; //拷貝構造,可以拷貝deque queue<int> que(deq); //100個5 queue<int> que2(100,5); //運算符重載 que2 = que; ...
  • 集合的理解和好處 數組一旦定義,長度即固定,不能修改。要添加新元素需要新建數組,然後迴圈拷貝,非常麻煩 集合可以動態保存任意多個對象,使用比較方便 提供餓了一系列方便的操作對象的方法:add、remove、set、get等 使用集合添加、刪除新元素的示意代碼,簡潔明瞭 集合主要是兩組(單列集合,雙列 ...
  • 本文已經收錄到Github倉庫,該倉庫包含電腦基礎、Java基礎、多線程、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分散式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~ Github地址 如果訪問不了Github,可以訪 ...
  • 繼承(Inheritance) Odoo的一個強大方面是它的模塊化。模塊專用於業務需求,但模塊也可以相互交互。這對於擴展現有模塊的功能非常有用。例如,在我們的房地產場景中,我們希望在常規用戶視圖中直接顯示銷售人員的財產列表。 在介紹特定的Odoo模塊繼承之前,讓我們看看如何更改標準CRUD(創建、檢 ...
  • 項目介紹與環境搭建 1.項目學習前置知識 Java基礎知識 javaweb MySQL SpringBoot SSM(Spring,SpringMVC,MyBatis) Maven 2.學習收穫 瞭解企業項目開發的完整流程,增長開發經驗 瞭解需求分析的過程,提高分析和設計能力 對所學的技術進行靈活應 ...
  • 簡述 GDB, the GNU Project debugger, allows you to see what is going on 'inside' another program while it executes -- or what another program was doing a ...
  • token驗證 什麼是token?我相信很多開發者都或多或少聽過基於 token 的用戶鑒權和基於 session 的用戶鑒權,而今天說的 token 驗證就是第一種了。token 的意思是“令牌”,是用戶第一次登錄伺服器返回的,它能讓用戶不需要提交賬戶和密碼就能進行伺服器驗證身份,它是被放在請求頭 ...
  • @RequstBody、@RequstParam 這些註解是不是很熟悉?我們在開發Controller介面時經常會用到此類參數註解,那這些註解的作用是什麼?我們真的瞭解嗎? ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...