池式管理之線程池

1.初識線程池

問:線程池是什么?

答:維持管理一定數量的線程的池式結構。(維持:線程復用? 。 管理:沒有收到任務的線程處于阻塞休眠狀態不參與cpu調度 。一定數量:數量太多的線程會給操作系統帶來線程頻繁切換的開銷)

問:線程池解決的問題是什么?

答:異步執行耗時任務,充分利用多核,不過度占用核心業務線程。(耗時:耗時等待(io),耗時計算,不耗時的任務不會啟用線程池解放核心線程的壓力)

問:線程池是如何解決問題的?(工作原理)

答:生產者(核心線程)來使用線程,拋出任務到任務隊列,消費者(線程池線程)從隊列中取出任務進行執行。線程為空要阻塞線程池線程,避免輪詢隊列增加操作系統負擔。

問:為什么線程池總是使用隊列?

答:生產者對應push,消費者對應pop,操作隊列時間為O(1),占用鎖的時間短,可以使鎖的使用更加靈活。

2.用C++代碼實現:

1.線程池的類:

對外提供三個接口,內部兩個核心數據結構與一個核心工作函數

#pragma once#include <thread>
#include <functional>
#include <vector>// blockingqueue 僅僅只能用作指針或引用  不直接引入頭文件,避免循環依賴
template <typename T>
class BlockingQueue;class ThreadPool {
public:// 初始化線程池 explicit作用:避免ThreadPool tp = 3的賦值情況explicit ThreadPool(int threads_num);// 停止線程池~ThreadPool();// 發布任務到線程池void Post(std::function<void()> task); //function<void()>表示一個沒有參數無返回值的可調用對象private:void Worker();std::unique_ptr<BlockingQueue<std::function<void()>>> task_queue_; //unique_ptr作用:線程池獨占該任務隊列,若調用者輕易淺拷貝,提供報錯;在Pool離開作用域的時候,自動調用析構函數刪除隊列std::vector<std::thread> workers_;
};

2.對外三個接口以及核心工作函數的實現

#include "blockingqueue.h"
#include <memory>
#include "threadpool.h"ThreadPool::ThreadPool(int threads_num) {task_queue_ = std::make_unique<BlockingQueue<std::function<void()>>>();for (size_t i = 0; i < threads_num; ++i) {workers_.emplace_back([this] {Worker(); }); //this捕獲當前 調用ThreadPool的pool對象 ;worker為線程執行函數}
}// 停止線程池
ThreadPool::~ThreadPool() {task_queue_->Cancel();for (auto& worker : workers_) {if (worker.joinable())worker.join();}
}void ThreadPool::Post(std::function<void()> task) {task_queue_->Push(task);
}void ThreadPool::Worker() {while (true) {std::function<void()> task;if (!task_queue_->Pop(task)) {break;}task();}
}

3.核心數據結構:自定義隊列類的實現

class BlockingQueuePro {
public:BlockingQueuePro(bool nonblock = false) : nonblock_(nonblock) {}//提供給生產者(主)線程使用void Push(const T& value) {std::lock_guard<std::mutex> lock(prod_mutex_);prod_queue_.push(value);not_empty_.notify_one();}//提供給消費者線程使用bool Pop(T& value) {std::unique_lock<std::mutex> lock(cons_mutex_);if (cons_queue_.empty() && SwapQueue_() == 0) { return false;//隊列已關閉}value = cons_queue_.front();cons_queue_.pop();return true;}//提供給生產者(主)線程使用  銷毀線程池時調用void Cancel() {std::lock_guard<std::mutex> lock(prod_mutex_);nonblock_ = true;not_empty_.notify_all();}private:int SwapQueue_() {std::unique_lock<std::mutex> lock(prod_mutex_);//所有消費者進程阻塞在下面一行等待被喚醒 (正常喚醒 or 異常喚醒(線程池銷毀))not_empty_.wait(lock, [this] {return !prod_queue_.empty() || nonblock_; });std::swap(prod_queue_, cons_queue_);return cons_queue_.size();}bool nonblock_;//設置阻塞隊列的狀態,構造置0表示默認有阻塞,cancel中置為1表示無阻塞std::queue<T> prod_queue_;//STL里的隊列std::queue<T> cons_queue_;std::mutex prod_mutex_;std::mutex cons_mutex_;std::condition_variable not_empty_;//條件變量cond 用于線程間通信: 消費者wait 生產者喚醒
};

3.工作流程

初始化線程池,創建線程。線程在執行task()之前,阻塞在任務隊列的Pop,等待主業務線程將task 通過post加入到任務隊列后將某一線程喚醒(或者要銷毀任務隊列了喚醒所有線程)。所有任務執行完畢后,銷毀線程池(可選)。

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

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

相關文章

嬰兒 3D 安睡系統專利拆解:搭扣與智能系帶的鎖定機制及松緊調節原理

凌晨2點&#xff0c;你盯著嬰兒床里的小肉團直嘆氣。剛用襁褓裹成小粽子才哄睡的寶寶&#xff0c;才半小時就蹬開了裹布&#xff0c;小胳膊支棱得像只小考拉&#xff1b;你手忙腳亂想重新裹緊&#xff0c;結果越裹越松&#xff0c;裹布滑到脖子邊&#xff0c;寶寶突然一個翻身&…

pandas中df.to _dict(orient=‘records‘)方法的作用和場景說明

df.to _dict(orientrecords) 是 Pandas DataFrame 的一個方法&#xff0c;用于將數據轉換為字典列表格式。以下是詳細解釋及實例說明&#xff1a; 一、核心含義作用 將 DataFrame 的每一行轉換為一個字典&#xff0c;所有字典組成一個列表。 每個字典的鍵&#xff08;key&#…

阿里云Anolis OS 8.6的公有云倉庫源配置步驟

文章目錄一、備份現有倉庫配置&#xff08;防止誤操作&#xff09;二、配置阿里云鏡像源2.1 修改 BaseOS 倉庫2.2 修改 AppStream 倉庫三、清理并重建緩存四、驗證配置4.1 ?檢查倉庫狀態?&#xff1a;五、常見問題解決5.1 ?HTTP 404 錯誤5.2 ?網絡連接問題附&#xff1a;其…

回歸預測 | Matlab實現CNN-BiLSTM-self-Attention多變量回歸預測

回歸預測 | Matlab實現CNN-BiLSTM-self-Attention多變量回歸預測 目錄回歸預測 | Matlab實現CNN-BiLSTM-self-Attention多變量回歸預測預測效果基本介紹程序設計參考資料預測效果 基本介紹 1.Matlab實現CNN-BiLSTM融合自注意力機制多變量回歸預測&#xff0c;CNN-BiLSTM-self-…

103、【OS】【Nuttx】【周邊】文檔構建渲染:Sphinx 配置文件

【聲明】本博客所有內容均為個人業余時間創作&#xff0c;所述技術案例均來自公開開源項目&#xff08;如Github&#xff0c;Apache基金會&#xff09;&#xff0c;不涉及任何企業機密或未公開技術&#xff0c;如有侵權請聯系刪除 背景 接之前 blog 【OS】【Nuttx】【周邊】文…

轉換一個python項目到moonbit,碰到報錯輸出:編譯器對workflow.mbt文件中的類方法要求不一致的類型注解,導致無法正常編譯

先上結論&#xff1a;現在是moon test的時候有很多報錯&#xff0c;消不掉。問題在Trae中用GLM-4.5模型&#xff0c;轉換一個python項目到moonbit&#xff0c;碰到報錯輸出&#xff1a;報錯輸出經過多次嘗試修復&#xff0c;我發現這是一個MoonBit編譯器的bug。編譯器對workflo…

【C#補全計劃】事件

一、事件的概念1. 事件是基于委托的存在&#xff0c;是委托的安全包裹&#xff0c;讓委托的使用更具有安全性2. 事件是一種特殊的變量類型二、事件的使用1. 語法&#xff1a;event 委托類型 事件名;2. 使用&#xff1a;&#xff08;1&#xff09;事件是作為成員變量存在與類中&…

java內存緩存

我們在項目中會經常使Redis和Memcache,但是簡單項目就沒必要使用專門的緩存框架來增加系統的復雜性。用Java代碼邏輯就能實現內存級別的緩存。1.定時任務線程池使用ScheduledExecutorService結合ConcurrentHashMap&#xff0c;如果你使用的是ConcurrentHashMap&#xff0c;你可…

智能工廠生產監控大屏-vue純前端靜態頁面練習

學習前端還是非常有意思的&#xff0c;因為前端真的是可見即所得&#xff0c;可以做出來非常好看漂亮的頁面&#xff0c;最近我就在使用前端技術 做一些大屏報表&#xff0c;在制作這些大屏報表過程中&#xff0c;又熟練的練習了自己的學到的相關的前端技術&#xff0c;接下來把…

HTTP 協議詳細介紹

目錄一、HTTP 的基本概念與歷史演進1. 核心定義2. 歷史版本演進二、HTTP 的核心工作原理1. 請求-響應模型2. 基于 TCP 的傳輸&#xff08;HTTP/1.1、HTTP/2&#xff09;三、HTTP 請求結構1. 請求行2. 請求頭3. 請求體四、HTTP 響應結構1. 狀態行2. 響應頭3. 響應體五、HTTP 與 …

正則化:從過擬合到泛化的「平衡藝術」

在機器學習領域&#xff0c;有一個幾乎所有從業者都會遇到的「噩夢」&#xff1a;模型在訓練集上表現完美&#xff08;損失趨近于0&#xff09;&#xff0c;但在測試集上卻大幅「翻車」。這種現象被稱為「過擬合」&#xff08;Overfitting&#xff09;&#xff0c;它像一把雙刃…

[Python 基礎課程]根據描述定義一個 Person 類

人都屬于人類這個物種&#xff0c;每一個人都會有姓名和年齡&#xff0c;人都可以介紹自己&#xff0c;隨著時間的流逝&#xff0c;人都會增加年齡&#xff0c;每一個人都能獲取到自己的物種信息。 我們的抽象過程&#xff1a; 所有的 Person 對象都應該有一個共同的屬性來表示…

熱門手機機型重啟速度對比

以下是2023-2024年市場主流熱門手機機型的重啟速度對比分析&#xff0c;基于公開測試數據和用戶反饋整理&#xff08;數據會因系統版本和測試環境不同存在波動&#xff09;&#xff1a;旗艦機型重啟速度排名&#xff08;冷啟動&#xff09;排名機型平均重啟時間關鍵配置優化技術…

第454題.四數相加II

第454題.四數相加II 力扣題目鏈接(opens new window) 給定四個包含整數的數組列表 A , B , C , D ,計算有多少個元組 (i, j, k, l) &#xff0c;使得 A[i] B[j] C[k] D[l] 0。 為了使問題簡單化&#xff0c;所有的 A, B, C, D 具有相同的長度 N&#xff0c;且 0 ≤ N ≤…

力扣top100(day04-05)--堆

本文為力扣TOP100刷題筆記 筆者根據數據結構理論加上最近刷題整理了一套 數據結構理論加常用方法以下為該文章&#xff1a; 力扣外傳之數據結構&#xff08;一篇文章搞定數據結構&#xff09; 215. 數組中的第K個最大元素 class Solution {// 快速選擇遞歸函數int quickselect(…

CCS雙軸相位偏移光源 讓淺凹痕無處遁形

在工業檢測中&#xff0c;淺凹痕表面檢測對精度和可靠性要求極高&#xff0c;工業光源在此過程中扮演著關鍵角色&#xff0c;工業光源通過精準的光學設計&#xff08;角度、波長、強度&#xff09;將肉眼不可見的淺凹痕轉化為可量化的光學信號&#xff0c;是實現高精度自動化檢…

專題三_二分_x 的平方根

一&#xff1a;題目解釋&#xff1a;返回x的算數平方根&#xff0c;如果是小數&#xff0c;則舍去小數部分&#xff0c;返回整數即可&#xff01;二&#xff1a;算法①&#xff1a;暴力從1開始求平方&#xff0c;最后要么直接找到一個值的平方為x&#xff0c;要么發現x在兩個相…

Python 操作 Redis 的客戶端庫 redis-py

Python 操作 Redis 的客戶端庫 redis-py1. Installation2. Connect and test3. Connection Pools4. Redis Commands4.1. set(name, value, exNone, pxNone, nxFalse, xxFalse, keepttlFalse, getFalse, exatNone, pxatNone)4.1.1. setnx(name, value)4.1.2. setex(name, time, …

社區物業HCommunity本地部署手冊

HC小區管理系統安裝手動版 更多文章參考&#xff1a; http://www.homecommunity.cn/pages/hc/hcH5_cn.html 1.0 說明 很多開發不太喜歡用梓豪安裝&#xff0c;希望通過手工自己安裝&#xff0c;這個就需要開發人員 有一定的安裝軟件能力&#xff0c;比如能夠自行安裝mysql能…

單例模式-使用局部變量懶漢不用加鎖

在 C11 及之后&#xff0c;“局部靜態變量懶漢”&#xff08;Meyers’ Singleton&#xff09;不需要自己加鎖&#xff0c;標準已經幫你做好了線程安全。 Singleton& getInstance() {static Singleton inst; // ← 這一句并發時只會初始化一次return inst; }首次調用時&am…