【sylar-webserver】5 協程調度模塊

文章目錄

  • 設計思路
    • 三種協程的切換

協程調度模塊,需要把前面的線程模塊和協程模塊結合使用 ~

設計思路

  • 構造函數定義 線程池 基本信息。
  • start(),創建線程池,每個線程創建都執行 run()。
  • 每個線程在 run() 里,查找任務隊列 m_tasks。如果獲取到任務后,創建協程并切換執行 ~ 如果沒任務切換到 idel 協程等待 ~
  • 添加任務到 m_tasks。
  • stop(),調用tickle(),喚醒所有線程,等待所有的任務完成。

主要的函數:

  1. 構造函數
  2. Scheduler(size_t threads, bool use_caller, const std::string &name) // 模板函數,添加任務
  3. start()
  4. run()
  5. stop()

主要的變量:

  • 線程變量:
    • static thread_local Scheduler* t_scheduler;當前線程的調度器,同一個調度器下的所有線程貢獻同一個實例。
    • static thread_local Fiber* t_scheduler_fiber; 當前線程的調度協程,每個線程都獨一份。
  • Scheduler類變量
    • std::vector<Thread::ptr> m_threads; 線程池
    • std::list<ScheduleTask> m_tasks; 任務隊列
    • bool m_useCaller; 主線程是否添加調度
      • 當 m_useCaller = true; 主線程添加調度
      • Fiber::ptr m_rootFiber; 調度器所在線程的調度協程
      • int m_rootThread; 調度所在的線程id

具體調度需要細分情況:

  • 主線程不添加到調度器
    這種較為簡單。

    • Scheduler(),定義線程池變量
    • start(),創建子線程 執行 run()
    • run(),如果是子線程,需要創建主協程賦值給 t_scheduler_fiber 作為調度協程。idle_fiber協程。cb_fiber任務協程。從任務隊列拿去任務,然后設置cb_fiber,切換執行。(主協程 <----> cb_fiber)。如果沒有任務,切換idel協程,阻塞(iomanager里會使用epoll_wait重寫這個方法,這里還只是象征性的 等待。重寫需要注意,idle_fiber是在while循環里,也就是只要不stop,idle_fiber會一直存在。)(主協程 <----> idle_fiber)。
    • stop(),設置m_stopping,喚起子線程,等待任務執行結束。【純線程池 模型下,只要是外部線程即可stop】
  • 主線程添加到調度器
    其實這里,最重要的是 三協程的切換設置。
    (主協程 — 調度協程 — 任務協程)

    • Scheduler(),定義線程池變量。創建調度協程賦值 m_rootFiber 作為當前主線程的調度協程,運行run()。賦值t_scheduler_fiber = m_rootFiber.get() ,這就是當前主線程的調度協程。賦值 m_rootThread 當前主線程(用于判斷是否是主線程)。
    • start(),同上,創建子線程,執行run()
    • run(),此時額外增加 主線程的 調度過程。如果是主線程,那么 t_scheduler_fiber 已經賦值為調度協程。直接拿去任務執行,或者切換idle等待。
    • stop(),特殊性在于,主線程一直是主協程在 初始化/添加任務。只有在stop里,切換到 m_rootFiber 調度協程消費任務。【use_caller 模式下執行stop(),必須是主線程,因為我們需要 切換到 主線程里的調度協程 消費一下任務】

三種協程的切換

對于 主協程,調度協程,任務協程。

重構了 協程模塊 里的 yield 和 resume
yield:任務協程 --> 調度協程 —> 主協程
resume: 主協程 —> 調度協程 —> 任務協程

Fiber增加一個類變量
bool m_runInScheduler; // 本協程是否參與調度器調度,相當于當前協程是否是任務協程。

void Fiber::yield(){SYLAR_ASSERT(m_state == TERM || m_state == RUNNING)     // 當前子協程可以是 TERM,RUNNINGif(m_state != TERM){    // 如果沒有結束,中途進行yield,狀態設置為READY,可能還會回來繼續執行。m_state = READY;}if(m_runInScheduler){if(swapcontext(&m_ctx, &(Scheduler::GetMainFiber()->m_ctx))){...}}else{if(swapcontext(&m_ctx, &(t_thread_fiber->m_ctx))){...}}
}void Fiber::resume(){SYLAR_ASSERT(m_state == READY);// 切換前,提前設置狀態和 當前線程運行的協程。SetThis(this);m_state = RUNNING;if(m_runInScheduler){ // 相當于當前協程,是任務協程。 t_scheduler_fiber --> t_fiberif(swapcontext(&(Scheduler::GetMainFiber()->m_ctx), &m_ctx)){...}}else { // t_thread_fiber --> t_scheduler_fiberif(swapcontext(&(t_thread_fiber->m_ctx), &m_ctx)){...}}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74649.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74649.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74649.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Go 語言規范學習(1)

文章目錄 IntroductionNotation示例&#xff08;Go 語言的 if 語句&#xff09;&#xff1a; Source code representationCharacters例子&#xff1a;變量名可以是中文 Letters and digits Lexical elementsCommentsTokensSemicolons例子&#xff1a;查看程序所有的token Ident…

探索抓包利器ProxyPin,實現手機APP請求抓包,支持https請求

以下是ProxyPin的簡單介紹&#xff1a; - ProxyPin是一個開源免費HTTP(S)流量捕獲神器&#xff0c;支持 Windows、Mac、Android、IOS、Linux 全平臺系統- 可以使用它來攔截、檢查并重寫HTTP(S)流量&#xff0c;支持捕獲各種應用的網絡請求。ProxyPin基于Flutter開發&#xff0…

深度學習3-pytorch學習

深度學習3-pytorch學習 Tensor 定義與 PyTorch 操作 1. Tensor 定義&#xff1a; Tensor 是 PyTorch 中的數據結構&#xff0c;類似于 NumPy 數組。可以通過不同方式創建 tensor 對象&#xff1a; import torch# 定義一個 1D Tensor x1 torch.Tensor([3, 4])# 定義一個 Fl…

深入淺出Spring-Boot-3.x.pdf

通過網盤分享的文件&#xff1a;深入淺出Spring-Boot-3.x.pdf 鏈接: https://pan.baidu.com/s/10ZkhmeIXphEwND9Rv4EBlg?pwduatm 提取碼: uatm

springboot啟動事件CommandLineRunner使用

什么是CommandRunner CommandRunner是springboot啟動完成時會調用的一個runner 啟動參數會傳遞到這個runner 我們能用來做一些初始化工作和緩存預熱等工作 ApplicationRunner VS CommandRunner? 這兩個Runner作用一樣 只是得到的啟動參數格式不一樣 前者是一個Argument對象…

數據可視化TensorboardX和tensorBoard安裝及使用

tensorBoard 和TensorboardX 安裝及使用指南 tensorBoard 和 TensorBoardX 是用于可視化機器學習實驗和模型訓練過程的工具。TensorBoard 是 TensorFlow 官方提供的可視化工具&#xff0c;而 TensorBoardX 是其社區驅動的替代品&#xff0c;支持 PyTorch 等其他框架。以下是它…

藍橋杯C++基礎算法-多重背包

這段代碼實現了一個多重背包問題的動態規劃解法。多重背包問題與完全背包問題類似&#xff0c;但每個物品有其數量限制。以下是代碼的詳細思路解析&#xff1a; 1. 問題背景 給定 n 個物品&#xff0c;每個物品有其體積 v[i]、價值 w[i] 和數量 s[i]&#xff0c;以及一個容量為…

【SUNO】【AI作詞】【提示詞】

仿寫歌詞提示詞模板&#xff08;升級版&#xff09; 一、仿寫目標 風格定位 音樂風格&#xff1a; [填寫目標風格&#xff0c;如&#xff1a;民謠/流行/古風/電子/爵士等]參考案例&#xff1a;如《成都》的敘事民謠&#xff0c;《孤勇者》的勵志流行。 情感基調&#xff1a; […

26考研——樹與二叉樹_樹與二叉樹的應用(5)

408答疑 文章目錄 三、樹與二叉樹的應用哈夫曼樹和哈夫曼編碼哈夫曼樹的定義概念帶權路徑長度&#xff08;WPL&#xff09;計算示例分析 哈夫曼樹的構造算法描述哈夫曼樹的性質示例 哈夫曼編碼Huffman樹的編碼規則Huffman樹的構建過程前綴編碼前綴編碼的分析及應用 Huffman樹的…

【VUE】day06 動態組件 插槽 自定義指令 ESlint

【VUE】day06 動態組件 & 插槽 & 自定義指令 1. 動態組件1.1 通過不同的按鈕展示不同的組件1.1.1回顧click 1.2 keep-alive的使用1.3 keep-alive對應的生命周期函數1.3.1 keep-alive的include屬性1.3.2 exclude 1.4 組件注冊名稱和組件聲明時name的區別1.4.1 組件聲明時…

nodejs-原型污染鏈

還是老規矩&#xff0c;邊寫邊學&#xff0c;先分享兩篇文章 深入理解 JavaScript Prototype 污染攻擊 | 離別歌 《JavaScript百煉成仙》 全書知識點整理-CSDN博客 Ctfshow web入門 nodejs篇 web334-web344_web334 ctfshow-CSDN博客 334-js審計 var express require(expr…

Oracle 數據庫通過exp/imp工具遷移指定數據表

項目需求&#xff1a;從prod數據庫遷移和復制2個表(BANK_STATE&#xff0c;HBS)的數據到uat數據庫環境。 數據庫版本&#xff1a;Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 遷移工具&#xff1a;客戶端exp/imp工具 -- 執行命令 從Prod數據庫導出數據exp us…

企業級基于SpringBoot的MQTT的構建和使用

基于SpringBoot的MQTT配置及使用 首先要使用EMQX搭建一個MQTT服務器&#xff0c;參考文檔&#xff1a;EMQX快速開始 本著開源分享的觀點&#xff0c;閑話不多說&#xff0c;直接上代碼 導入Maven <dependency><groupId>org.springframework.integration</gro…

26考研——圖_圖的代碼實操(6)

408答疑 文章目錄 五、圖的代碼實操圖的存儲鄰接矩陣結構定義初始化插入頂點獲取頂點位置在頂點 v1 和 v2 之間插入邊獲取第一個鄰接頂點獲取下一個鄰接頂點顯示圖 鄰接表結構定義初始化圖插入頂點獲取頂點位置在頂點 v1 和 v2 之間插入邊獲取第一個鄰接頂點獲取下一個鄰接頂點…

開源webmail郵箱客戶端rainloop的分支版本SnappyMail 設置發件人允許多重身份

RainLoop已多年未更新&#xff0c;SnappyMail 是 RainLoop 的分支&#xff0c;由社區維護。SnappyMail 不僅修復了漏洞&#xff0c;還增加了更多功能和優化。對 IMAP 支持更好&#xff0c;移動端體驗也比 RainLoop 更細致。 安裝過程和設置跟RainLoop一樣&#xff1a; 以寶塔面…

海量數據場景題--查找兩個大文件的URL

查找兩個大文件共同的URL 給定 a、b 兩個文件&#xff0c;各存放 50 億個 URL&#xff0c;每個 URL 各占 64B&#xff0c;找出 a、b 兩個文件共同的 URL。內存限制是 4G。 操作邏輯&#xff1a; 使用哈希函數 hash(URL) % 1000? 將每個URL映射到0-999的編號 文件A切割為a0, a1…

簡單ELK框架搭建

簡介 ELK 框架是一套開源的日志管理和分析工具&#xff0c;由 Elasticsearch、Logstash 和 Kibana 三個主要組件組成&#xff0c;現在新增了Filebeat組件&#xff0c;可以更高效的收集數據。 Elasticsearch&#xff1a;是一個分布式、高可擴展的開源搜索引擎&#xff0c;能快速…

VS Code 中 .history`文件的來源與 .gitignore`的正確使用

引言 在使用 VS Code 進行 Git 版本控制時&#xff0c;有時會發現項目中多出一個 .history 目錄&#xff0c;并被 Git 識別為未跟蹤文件。本文將解釋 .history 的來源&#xff0c;并提供 .gitignore 的正確配置方法&#xff0c;確保開發環境的整潔性。 1. .history 文件的來源…

網絡之數據鏈路層

數據鏈路層 數據鏈路層目標 TCP/IP提供了一種能力, 將數據可靠的從 B 跨網絡送到 C 主機, 這期間是由無數次局域網轉發構成的, 比如 主機B 到 路由器F 就是一次局域網通信的問題, 而數據鏈路層就是研究數據是如何在局域網內部轉發的. 也就是說, 應用層是進行數據的處理, 傳輸…

A Brief History: from GPT-1 to GPT-3

This is my reading notes of 《Developing Apps with GPT-4 and ChatGPT》. In this section, we will introduce the evolution of the OpenAI GPT medels from GPT-1 to GPT-4. GPT-1 In mid-2018, OpenAI published a paper titled “Improving Language Understanding …