免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      「Linux學(xué)習(xí)」高并發(fā)服務(wù)器框架 線程池介紹+線程池封裝

      「Linux學(xué)習(xí)」高并發(fā)服務(wù)器框架 線程池介紹+線程池封裝

      目錄

      前言

      本文主要學(xué)習(xí) Linux內(nèi)核編程 ,結(jié)合 Visual Studio 2019 進(jìn)行跨平臺編程,內(nèi)容包括線程池介紹以及線程池封裝

      一、線程池介紹

      線程池基本概念

      • 線程池 是預(yù)先創(chuàng)建線程的一種技術(shù) (服務(wù)器真正意義上實(shí)現(xiàn)高并發(fā)就必須用線程池)
      • 舉個例子:生活中的水池,是裝東西的容器,用來裝水的,線程池當(dāng)然就是拿來裝線程的
      • 線程池在任務(wù)還沒有到來之前,創(chuàng)建一定數(shù)量的線程,放入空閑隊(duì)列中,這些線程都是處于阻塞狀態(tài),不消耗CPU,但占用較小的內(nèi)存空間
      • 當(dāng)新任務(wù)到來時,緩沖池選擇一個空閑線程,把任務(wù)傳入此線程中運(yùn)行,如果緩沖池已經(jīng)沒有空閑線程,則新建若干個線程,當(dāng)系統(tǒng)比較空閑時,大部分線程都一直處于暫停狀態(tài),線程池自動銷毀一部分線程,回收系統(tǒng)資源

      線程池組成部分

      • 線程池類

      維護(hù)工作者線程隊(duì)列(包括空閑與忙碌隊(duì)列)

      維護(hù)一個任務(wù)隊(duì)列

      維護(hù)一個線程池調(diào)度器指針

      • 線程池調(diào)度器 (本身也是一個線程)

      負(fù)責(zé)線程調(diào)度

      負(fù)責(zé)任務(wù)分配

      • 工作者線程類 (線程池中的線程類的封裝)
      • 任務(wù)隊(duì)列
      • 任務(wù)接口 (實(shí)際的業(yè)務(wù)邏輯都繼承自該接口)

      線程池工作原理

      根據(jù)服務(wù)器的需要,來設(shè)置線程的數(shù)量,可能是10條、20條、30條,根據(jù)服務(wù)器的承載,10條不代表只能做10個任務(wù),總有任務(wù)做的快,有的做的慢,可能可以完成20個任務(wù)

      舉個例子:如上動圖所示,當(dāng)我們服務(wù)器收到一個注冊業(yè)務(wù),是一個服務(wù)器要執(zhí)行的任務(wù),它會進(jìn)入到任務(wù)隊(duì)列,隊(duì)列先進(jìn)先出,順次執(zhí)行,任務(wù)會喚醒空閑列表當(dāng)中的一個空閑的線程,接到任務(wù)之后,空閑線程會從空閑列表中消失,進(jìn)入到忙碌列表,去完成對應(yīng)的任務(wù),完成任務(wù)后,從忙碌列表中出去,到空閑列表繼續(xù)等待新任務(wù)

      如果,所有的線程都在忙,都在做任務(wù),這時候登錄進(jìn)來,先進(jìn)入任務(wù)隊(duì)列,會創(chuàng)建一個新的線程來接這個任務(wù),當(dāng)所有線程都完成任務(wù),回到空閑列表后,新創(chuàng)建的線程銷毀,留下原先設(shè)置的對應(yīng)數(shù)量線程(類似,保留老員工,把實(shí)習(xí)生裁員)

      • 隊(duì)列: 先進(jìn)先出
      • 空閑列表(鏈表): 不定長(有的時候可能需要創(chuàng)建新線程來接任務(wù))
      • 忙碌列表(鏈表): 不定長(有的時候可能需要創(chuàng)建新線程來接任務(wù))

      話不多說,咱們上號,封裝一下線程池相關(guān)函數(shù),來進(jìn)行測試

      二、線程池代碼封裝

      main.cpp

      • 主函數(shù),設(shè)置10條線程,來執(zhí)行30個任務(wù)

      #include #include #include “ThreadPool.h”#include “ChildTask.h”using namespace std;int main(){ThreadPool* pool = new ThreadPool(10);//10條線程for (int i = 0; i pushTask(task);}while (1) {}return 0;}

      ThreadPool.h

      • 對線程池進(jìn)行設(shè)計(jì),核心包括 最大、最小線程數(shù) , 忙碌列表 , 空閑列表 , 任務(wù)隊(duì)列 , 互斥量 , 條件變量 ,以及 線程執(zhí)行函數(shù)

      #pragma once#include //隊(duì)列#include //鏈表頭文件#include //線程頭文件#include //find查找#include #include “BaseTask.h”using namespace std;#define MIN_NUM 10//最小值 默認(rèn)參數(shù)class ThreadPool{public:ThreadPool(const int num = MIN_NUM);~ThreadPool();//判斷任務(wù)隊(duì)列是否為空bool QueueIsEmpty();//線程互斥量加鎖解鎖void Lock();void Unlock();//線程條件變量等待和喚醒void Wait();void WakeUp();//添加任務(wù)到任務(wù)隊(duì)列void pushTask(BaseTask* task);//從任務(wù)隊(duì)列移除任務(wù)BaseTask* popTask(BaseTask* task);//從忙碌回到空閑 工作結(jié)束void MoveToIdle(pthread_t id);//從空閑到忙碌 工作開始void MoveToBusy(pthread_t id);//線程執(zhí)行函數(shù)static void* RunTime(void* vo);private:int threadMinNum;//最大線程數(shù)量int threadMaxNum;//最小線程數(shù)量queuetaskQueue;//任務(wù)隊(duì)列l(wèi)istbusyList;//線程忙碌列表listidleList;//線程空閑列表pthread_mutex_t mutex;//互斥量:做鎖pthread_cond_t cond;//條件變量:讓線程等待或者喚醒};

      ThreadPool.cpp

      • 對函數(shù)進(jìn)行參數(shù)的設(shè)置,核心在于線程執(zhí)行函數(shù)上的設(shè)置,在工作前和工作完設(shè)置打印,方便我們進(jìn)行觀察

      #include “ThreadPool.h”ThreadPool::ThreadPool(const int num){this->threadMinNum = num;//條件變量、互斥量初始化pthread_mutex_init(&this->mutex, NULL);pthread_cond_init(&this->cond, NULL);pthread_t id;//線程num條創(chuàng)建for (int i = 0; i threadMinNum; i++){//線程創(chuàng)建pthread_create(&id, NULL, RunTime, this);this->idleList.push_back(id);//線程存入空閑列表}}ThreadPool::~ThreadPool(){}//任務(wù)隊(duì)列是否為空bool ThreadPool::QueueIsEmpty(){return this->taskQueue.empty();}//線程加鎖void ThreadPool::Lock(){pthread_mutex_lock(&this->mutex);}//線程解鎖void ThreadPool::Unlock(){pthread_mutex_unlock(&this->mutex);}//線程等待void ThreadPool::Wait(){pthread_cond_wait(&this->cond, &this->mutex);}//線程喚醒void ThreadPool::WakeUp(){pthread_cond_signal(&this->cond);}//添加任務(wù)到任務(wù)隊(duì)列void ThreadPool::pushTask(BaseTask* task){Lock();taskQueue.push(task);Unlock();WakeUp();}//從任務(wù)隊(duì)列移除任務(wù)BaseTask* ThreadPool::popTask(BaseTask* task){task = this->taskQueue.front();//從隊(duì)列頭取this->taskQueue.pop();//刪除隊(duì)列頭return task;}//從忙碌回到空閑 工作結(jié)束void ThreadPool::MoveToIdle(pthread_t id){list::iterator iter;iter = find(busyList.begin(), busyList.end(), id);if (iter != busyList.end()){//從忙碌移除this->busyList.erase(iter);//添加到空閑this->idleList.push_back(*iter);//this->idleList.push_back(id)}}//從空閑到忙碌 工作開始void ThreadPool::MoveToBusy(pthread_t id){list::iterator iter;iter = find(idleList.begin(), idleList.end(), id);if (iter != idleList.end()){//從空閑移除this->idleList.erase(iter);//添加到忙碌this->busyList.push_back(*iter);//this->idleList.push_back(id)}}//線程執(zhí)行函數(shù)void* ThreadPool::RunTime(void* vo){//拿到執(zhí)行線程自己的id 因?yàn)楹竺嬉幚砻β岛涂臻e的情況pthread_t id = pthread_self();//確保主線程與子線程分離,子線程結(jié)束后,資源自動回收pthread_detach(id);//線程參數(shù)獲取ThreadPool* argThis = (ThreadPool*)vo;while (true){argThis->Lock();//如果任務(wù)隊(duì)列為空 線程則一直等待 //知道任務(wù)隊(duì)列不為空則會被pushTask函數(shù)喚醒線程while (argThis->QueueIsEmpty()){argThis->Wait();}argThis->MoveToBusy(id);cout << "工作前 任務(wù)數(shù):" <taskQueue.size() << endl;cout << "工作前 busy:" <busyList.size() << endl;cout << "工作前 idle:" <idleList.size() << endl;cout << "———————————————–" Unlock();//任務(wù)工作task->working();//工作結(jié)束argThis->Lock();argThis->MoveToIdle(id);argThis->Unlock();cout << "工作完 任務(wù)數(shù):" <taskQueue.size() << endl;cout << "工作完 busy:" <busyList.size() << endl;cout << "工作完 idle:" <idleList.size() << endl;cout >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>” << endl;}return nullptr;}

      ChildTask.h

      • 子類配置

      #pragma once#include “BaseTask.h”#include #include //sleep頭文件using namespace std;class ChildTask :public BaseTask{public:ChildTask(char* data);~ChildTask();void working();};

      ChildTask.cpp

      • 子類設(shè)置延時模擬做任務(wù)的時間比較長

      #include “ChildTask.h”ChildTask::ChildTask(char* data) :BaseTask(data)//參數(shù)傳給父類{}ChildTask::~ChildTask(){}void ChildTask::working(){cout <data << "正在執(zhí)行……" << endl;sleep(3);//延時3秒 (模擬做業(yè)務(wù)的時間比較長)}

      BaseTask.h

      • 基類設(shè)置結(jié)構(gòu)體來裝業(yè)務(wù)

      #pragma once#include class BaseTask{public:BaseTask(char* data);~BaseTask();char data[1024]; //裝業(yè)務(wù)virtual void working() = 0;//虛函數(shù)};

      BaseTask.cpp

      • 基類配置

      #include “BaseTask.h”BaseTask::BaseTask(char* data){bzero(this->data, sizeof(this->data));//清空memcpy(this->data, data, sizeof(data));}BaseTask::~BaseTask(){delete this->data;//清除釋放}

      三、測試效果

      • 通過Linux連接VS進(jìn)行跨平臺編程,我們可以清晰的看到有幾個線程是在做任務(wù),幾個線程是空閑的,整個過程就很清晰直觀的展現(xiàn)出來了,如下動圖所示:
      • 10條線程做30個任務(wù)的全部記錄,如下如所示:

      四、總結(jié)

      創(chuàng)建線程池的好處

      • 線程池的使用,能讓我們搭建的高并發(fā)服務(wù)器真正意義上做到高并發(fā)
      • 降低資源消耗

      通過重復(fù)利用自己創(chuàng)建的線程降低線程創(chuàng)建和銷毀造成的消耗

      • 提高響應(yīng)速度

      當(dāng)任務(wù)到達(dá)時,任務(wù)可以不需要等待線程創(chuàng)建和銷毀就能立即執(zhí)行

      • 提高線程的可管理性

      線程式稀缺資源,如果無限的創(chuàng)建線程,不僅會消耗資源,還會降低系統(tǒng)的穩(wěn)定性

      使用線程池可以進(jìn)行統(tǒng)一分配,調(diào)優(yōu)和監(jiān)控

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
      (0)
      用戶投稿
      上一篇 2022年8月16日 09:35
      下一篇 2022年8月16日 09:35

      相關(guān)推薦

      • 為什么很多醫(yī)生勸病人不要吸煙,自己卻吧嗒吧嗒抽不停?

        我是醫(yī)生,也抽煙,一天兩包。 1,有多少醫(yī)生抽煙?在醫(yī)院里,大致上情況是,內(nèi)科醫(yī)生大多數(shù)不抽煙,外科醫(yī)生大多數(shù)抽煙好厲害。為什么這樣呢?工作性質(zhì),個人性格。內(nèi)科醫(yī)生一直處于緊張和糾…

        2022年4月19日
      • 別再假裝圣人蛋,酒足飯飽享清閑

        整天盯著新聞看, 今早氣得不吃飯; 平頭百姓圣人蛋, 餓死沒人來吊唁; 別再充高裝圣賢, 踏踏實(shí)實(shí)工作干; 不干沒人發(fā)工資, 最好快進(jìn)直播間; 也許有幸搶一塊, 酒足飯飽享清閑。

        2022年8月4日
      • 拿一份工資,領(lǐng)導(dǎo)卻讓做幾份活,該怎么辦呢?

        這種情況在目前很多企業(yè),公司都會出現(xiàn)。我是一個創(chuàng)業(yè)者,如果以我站在老板的角度來說這個事情,一個員工能做兩份活,是一個能力和毅力的體現(xiàn)。如果是兩年前打工者的角度,這個問題需要看幾種情…

        2022年4月12日
      • 王者榮耀:天魔繚亂返場來襲,最低只要60點(diǎn)券,準(zhǔn)備兩萬鉆石很賺

        在王者榮耀中,隨著版本更新內(nèi)容愈發(fā)豐富,但同時也帶來了諸如平衡太差的問題,因此更新的方向也發(fā)生了一些變化,從原本增加新英雄之類的內(nèi)容更改為以更新皮膚為主。而這種轉(zhuǎn)變也讓皮膚數(shù)量快速…

        2022年7月18日
      • 毛主席逝世后,女兒李敏致電張仙朋:你為什么還不來北京悼念爸爸

        1976年9月9日,毛主席在北京去世,全國都陷入了失去偉人的悲痛之中。毛主席的女兒李敏在整理賓客名單的時候發(fā)現(xiàn)張仙朋沒有來,她十分氣憤,并親自致電質(zhì)問張仙朋:“你為什么還不來北京悼…

        2022年8月22日
      • 社?;鸲径刃逻M(jìn)5股,增持6股

        2022年二季度末社?;鸸铂F(xiàn)身23只個股前十大流通股東榜。其中,新進(jìn)5只,增持6只。社?;鹬貍}股中,從前十大流通股東名單中社?;鸺覕?shù)來看,華工科技、恩華藥業(yè)2股有2家社?;稹?/p>

        2022年8月8日
      • 這個世界,只有一種去中心化

        有感于最近加密幣的市場,真的是人生起伏,比電影精彩百倍。 我有個好友,在比特幣市場投了一千多萬,去年行情好的時候,又湊錢投進(jìn)去五百多萬。上半年提醒過他一句,這個市場的基礎(chǔ)敘事已經(jīng)打…

        2022年6月17日
      • 在事業(yè)單位工作,月薪2000元有必要買汽車嗎?適合買什么樣的汽車?

        這個應(yīng)該根個人原因,離公交地鐵遠(yuǎn)、還要接送孩子等就應(yīng)該買一輛車,吉利不錯 、沒有上述情況就不用買車了! 現(xiàn)在的汽車五花八門,有小汽車,小電車,你量力而選總有適合你的, 假設(shè)你的月收…

        2022年4月16日
      • Matlab基礎(chǔ)入門手冊(第六章 符號運(yùn)算)

        第六章 符號運(yùn)算 1.53 符號對象 1.符號數(shù)值、變量和表達(dá)式的創(chuàng)建方法 2.認(rèn)識函數(shù) sym、syms 3.說明 符號數(shù)學(xué)工具箱 符號數(shù)學(xué)工具箱引入了一種特殊的數(shù)據(jù)類型 &#8…

        2022年6月19日
      • 前重量級拳王塞爾登境況堪憂,如今無家可歸,住在收容所里

        前世界重量級拳王布魯斯-塞爾登境況堪憂,如今已經(jīng)無家可歸了,不得不居住在新澤西州紐瓦克的一處收容所中。塞爾登的同鄉(xiāng)、已經(jīng)退役的超輕量級拳手丹尼爾-麥克德莫特組織了一場募捐活動。麥克…

        2022年7月21日

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時間:周一至周五,10:30-18:30,節(jié)假日休息