欧美日韩在线第一页-欧美日韩在线观看精品-欧美日韩在线观看一区二区-欧美日韩在线免费看-欧美日韩在线视频不卡一区二区三区

編程代碼
新聞詳情

C++11多線程編程(六)——線程池的實現

發布時間:2021-01-06 16:30:00 瀏覽次數:2170

一、為何需要線程池

那么為什么我們需要線程池技術呢?多線程編程用的好好的,干嘛還要引入線程池這個東西呢?引入一個新的技術肯定不是為了裝酷,肯定是為了解決某個問題的,而服務端一般都是效率問題。

我們可以看到多線程提高了CPU的使用率和程序的工作效率,但是如果有大量的線程,就會影響性能,因為要大量的創建與銷毀,因為CPU需要在它們之間切換。線程池可以想象成一個池子,它的作用就是讓每一個線程結束后,并不會銷毀,而是放回到線程池中成為空閑狀態,等待下一個對象來使用。

C++11多線程編程(六)——線程池的實現

二、C++中的線程池

但是讓人遺憾的是,C++并沒有在語言級別上支持線程池技術,總感覺C++委員會對多線程的支持像是猶抱琵琶半遮面的羞羞女一樣,無法完全的放開。

雖然無法從語言級別上支持,但是我們可以利用條件變量和互斥鎖自己實現一個線程池。這里就不得不啰嗦幾句,條件變量和互斥鎖就像兩把利劍,幾乎可以實現多線程技術中的大部分問題,不管是生產消費者模型,還是線程池,亦或是信號量,所以我們必須好好掌握好這兩個工具。

#ifndef _THREADPOOL_H
#define _THREADPOOL_H
#include <vector>
#include <queue>
#include <thread>
#include <iostream>
#include <condition_variable>
using namespace std;
 
const int MAX_THREADS = 1000; //最大線程數目
 
template <typename T>
class threadPool
{
public:
    threadPool(int number = 1);
    ~threadPool();
    bool append(T *task);
    //工作線程需要運行的函數,不斷的從任務隊列中取出并執行
    static void *worker(void *arg);
    void run();
 
private:
    //工作線程
    vector<thread> workThread;
    //任務隊列
    queue<T *> taskQueue;
    mutex mt;
    condition_variable condition;
    bool stop;
};
 
template <typename T>
threadPool<T>::threadPool(int number) : stop(false)
{
    if (number <= 0 || number > MAX_THREADS)
        throw exception();
    for (int i = 0; i < number; i++)
    {
        cout << "create thread:" << i << endl;
        workThread.emplace_back(worker, this);
    }
}
template <typename T>
inline threadPool<T>::~threadPool()
{
    {
        unique_lock<mutex> unique(mt);
        stop = true;
    }
    condition.notify_all();
    for (auto &wt : workThread)
        wt.join();
}
template <typename T>
bool threadPool<T>::append(T *task)
{
    //往任務隊列添加任務的時候,要加鎖,因為這是線程池,肯定有很多線程
    unique_lock<mutex> unique(mt);
    taskQueue.push(task);
    unique.unlock();
    //任務添加完之后,通知阻塞線程過來消費任務,有點像生產消費者模型
    condition.notify_one();
    return true;
}
template <typename T>
void *threadPool<T>::worker(void *arg)
{
    threadPool *pool = (threadPool *)arg;
    pool->run();
    return pool;
}
template <typename T>
void threadPool<T>::run()
{
    while (!stop)
    {
        unique_lock<mutex> unique(this->mt);
        //如果任務隊列為空,就停下來等待喚醒,等待另一個線程發來的喚醒請求
        while (this->taskQueue.empty())
            this->condition.wait(unique);      
        T *task = this->taskQueue.front();
        this->taskQueue.pop();
        if (task)
            task->process();
    }
}
#endif

三、線程池代碼解析

  1. 對于線程池ThreadPool,必須要有構造和析構函數,構造函數中,創建N個線程(這個自己指定),插入到工作線程當中,工作線程可以是vector結構。工作線程中的線程具體要做什么呢?進入線程的時候必要用unique_lock進程加鎖處理,不能讓其他線程以及主線程影響到要處理的這個線程。判斷任務隊列是否為空,如果為空,則利用條件變量中的wait函數來阻塞該線程,等待任務隊列不為空之后喚醒它。然后取出任務隊列中的任務,執行任務中的具體操作。
  2. 接著將任務放入任務隊列taskQueue,這里的任務是外部根據自己的業務自己定義的,可以是對象,可以是函數,結構體等等,而任務隊列這里定義為queue結構,一定要記得將任務放入任務隊列的時候,要在之前加鎖,放入之后再解鎖,這里的加鎖解鎖可以用unique_lock結構,當然也可以用mutex結構,而放入任務隊列之后就可以用條件變量的notify_one函數通知阻塞的線程來取任務處理了。
  3. 看過我之前寫的《生產消費者模型之條件變量》的朋友對以上代碼有點熟悉,沒錯,線程池的實現就有點像是生產消費者模型,append()就像是生產者,不斷的將任務放入隊列,run()函數就像消費者,不斷的從任務隊列中取出任務來處理,生產消費的兩頭分別用notify_one()和wait()來喚醒和阻塞。更加詳細的介紹可以去看我的上一篇文章。
  4. 最后寫一個main文件來調用線程池的相關接口,main文件里定義一個任務對象,然后是main函數。
#include "threadPool.h"
#include <string>
using namespace std;
class Task
{
private:
    int total = 0;
 
public:
    void process();
};
 
//任務具體實現什么功能,由這個函數實現
void Task::process()
{
    //這里就輸出一個字符串
    cout << "task successful! " << endl;
    this_thread::sleep_for(chrono::seconds(1));
}
 
template class std::queue<Task>;
int main(void)
{
    threadPool<Task> pool(1);
    std::string str;
    while (1)
    {
        Task *task = new Task();
        pool.append(task);
        delete task;
    }
}

以上就是線程池的實現部分,充分利用條件變量和互斥鎖來實現,模型可以參考生產消費者模型。以上代碼部分來自網絡,根據自己的需求更改。

在線客服 雙翌客服
客服電話
  • 0755-23712116
  • 13822267203
主站蜘蛛池模板: 免费一级毛片免费播放| 免费看污又色又爽又黄视频| 瑟瑟网站在线观看| 国产欧美日韩另类一区乌克兰 | 久青草国产高清在线视频| 久久国产精品国产精品| 亚洲精品人成网在线播放影院| 麻豆影视在线观看| 91精品国产欧美一区二区| 国产伦一区二区三区高清| 成人午夜影视全部免费看| 久久国产乱子免费精品| 欧日韩一区二区三区| 爱干tv| 国产亚洲精品久久午夜| 亚洲国产视频网| chinese国产一区二区| 欧美国产亚洲一区| 最新国产在线播放| 欧美日比视频| 日韩一区二区三区免费| 亚洲人成在线精品不卡网| 国产一区二区三区高清| 香蕉依依精品视频在线播放| 青青久久久| 久久国产精品99精品国产| 男人的天堂色| 高清在线一区二区三区亚洲综合| 国产一区二区高清| 中文字幕欧美亚洲| 亚洲色图综合网| 91精品免费观看老司机| 男人懂的网站| 一级不卡毛片免费| 另类在线| 看黄在线| 成人看的一级毛片| a级小视频| 狠狠综合久久久久综合小说网 | 大伊香蕉精品视频在线天堂| 日本免费人成在线网站|