" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ 學(xué)習(xí)筆記實(shí)戰(zhàn)寫一個簡單的線程池示例

 更新時間:2023年10月29日 15:57:16   作者:Totn  
這篇文章主要為大家介紹了C++實(shí)現(xiàn)一個簡單的線程池學(xué)習(xí)實(shí)戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

線程池的工作原理

  • 在構(gòu)造函數(shù)中,創(chuàng)建指定數(shù)量的工作線程,并將它們存儲在 workers 向量中。
  • 每個工作線程都通過無限循環(huán)來執(zhí)行任務(wù)隊(duì)列中的任務(wù)。
  • 設(shè)置一個public函數(shù),接收新任務(wù),封裝為 std::function<void()> 并添加到任務(wù)隊(duì)列中。
  • 等待的工作線程會被喚醒并獲取任務(wù)執(zhí)行,直到線程池被銷毀或調(diào)用 stop() 函數(shù)停止。

第一步, 創(chuàng)建指定數(shù)量的工作線程

class ThreadPool {
public:
    ThreadPool(int num){
        // 啟動指定數(shù)量的線程
        for(int i = 0; i < num; i++ ) {
            // 使用循環(huán)創(chuàng)建指定數(shù)量的工作線程。每個工作線程都是通過`emplace_back`函數(shù)向`workers`容器中添加一個lambda函數(shù)創(chuàng)建的
            // 添加一個lambda函數(shù)即為創(chuàng)建一個線程
            workers.emplace_back([this]{
                // code...
            });
      }
    }
private:
    // 用向量儲存線程
    std::vector<std::thread> workers;
}

第二步在每個線程中啟動死循環(huán),依次從任務(wù)隊(duì)列中取中任務(wù),直到隊(duì)列為空或設(shè)置stop標(biāo)識為true;

第二步,在第一步基礎(chǔ)上,添加代碼

class ThreadPool {
public:
    ThreadPool(int num): stoped(false) {
        // 啟動指定數(shù)量的線程
        for(int i = 0; i < num; i++ ) {
            // 使用循環(huán)創(chuàng)建指定數(shù)量的工作線程。每個工作線程都是通過`emplace_back`函數(shù)向`workers`容器中添加一個lambda函數(shù)創(chuàng)建的
            // 添加一個lambda函數(shù)即為創(chuàng)建一個線程
            workers.emplace_back([this]{
                // 死循環(huán)
                while(true) {
                    // 設(shè)置一個task接收從隊(duì)列中取出的任務(wù)
                    std::function<void()> task;
                    {
                        // 從隊(duì)列中取任務(wù)要加鎖,以避免重復(fù)讀
                        std::unique_lock<std::mutex> lock(ququeMutex);
                        // 如果stoped==true,或任務(wù)不為空,則使當(dāng)前線程等待
                        condition.wait(lock, [this]{ return stroped || !tasks.empty(); });
                        // 設(shè)置stoped為true后,則等到任務(wù)都完成為退出(tasks任務(wù)隊(duì)列為空)
                        if (stoped && tasks.empty()) {
                            return;
                        }
                        // 從隊(duì)列中接收任務(wù)
                        task = std::move(tasks.front());
                        // 彈出已經(jīng)接收的任務(wù)
                        tasks.pop();
                    }
                    // 以上代碼使用{}限制了作用域,在域內(nèi)啟用的鎖queueMutex在域結(jié)束后自動解鎖
                }
            });
      }
    }
    // 設(shè)置停止標(biāo)識
    void stop() {
        std::unique_lock<std::mutex> lock(queueMutex);
        stoped = true;
    }
private:
    // 用向量儲存線程
    std::vector<std::thread> workers;
    // 工作隊(duì)列
    std::queue<std::function<void()> tasks;
    // 隊(duì)列互斥鎖
    std::mutex queueMutex;
    // 條件變量
    std::condition_variable condition;
    // stop標(biāo)識
    bool stoped;
}

第三步,設(shè)置一個函數(shù)用從外部接收任務(wù)

// class ThreadBool...
template<class F>
void enqueue(F&& f){
    {
        // 在域內(nèi)啟用鎖, 保證加任務(wù)時沒沖突
        std::unique_lock<std::mutex> lock(queueMutex);
        // 轉(zhuǎn)發(fā)任務(wù)到tasks隊(duì)列中
        tasks.emplace(std::forword<F>(f));
    }
    // 通知一個線程起來接活
    condition.notify_one();
}
// ...

第四步,設(shè)置析構(gòu)函數(shù)等待所有線程執(zhí)行完成

// class ThreadBool
~ThreadPool(){
?。?
         std::unique_lock<std::mutex> lock(queueMutex);
      stoded = true;
     }
     // 阻塞等待所有線程
  for(std::thread& worker: workers){
      worker.join();
  }
}

最后完整代碼

#include <vector>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iostream>
thread_local int thr_num;
class Task{
    public run(int num = 0) {
        thr_num = num;
        std::cout << "當(dāng)前任務(wù)號是" << thr_num << std::endl;
    }
}
class ThreadPool {
public:
    ThreadPool(int num): stoped(false) {
        // 啟動指定數(shù)量的線程
        for(int i = 0; i < num; i++ ) {
            // 使用循環(huán)創(chuàng)建指定數(shù)量的工作線程。每個工作線程都是通過`emplace_back`函數(shù)向`workers`容器中添加一個lambda函數(shù)創(chuàng)建的
            // 添加一個lambda函數(shù)即為創(chuàng)建一個線程
            workers.emplace_back([this]{
                // 死循環(huán)
                while(true) {
                    // 設(shè)置一個task接收從隊(duì)列中取出的任務(wù)
                    std::function<void()> task;
                    {
                        // 從隊(duì)列中取任務(wù)要加鎖,以避免重復(fù)讀
                        std::unique_lock<std::mutex> lock(ququeMutex);
                        // 如果stoped==true,或任務(wù)不為空,則使當(dāng)前線程等待
                        condition.wait(lock, [this]{ return stroped || !tasks.empty(); });
                        // 設(shè)置stoped為true后,則等到任務(wù)都完成為退出(tasks任務(wù)隊(duì)列為空)
                        if (stoped && tasks.empty()) {
                            return;
                        }
                        // 從隊(duì)列中接收任務(wù)
                        task = std::move(tasks.front());
                        // 彈出已經(jīng)接收的任務(wù)
                        tasks.pop();
                    }
                    // 以上代碼使用{}限制了作用域,在域內(nèi)啟用的鎖queueMutex在域結(jié)束后自動解鎖
                }
            });
      }
    }
    // 設(shè)置停止標(biāo)識
    void stop() {
        std::unique_lock(std::mutex )
        stoped = true;
    }
private:
    // 用向量儲存線程
    std::vector<std::thread> workers;
    // 工作隊(duì)列
    std::queue<std::function<void()> tasks;
    // 隊(duì)列互斥鎖
    std::mutex queueMutex;
    // 條件變量
    std::condition_variable condition;
    // stop標(biāo)識
    bool stoped;
}
int main() {
    ThreadPool tp(4);
    Task task;
    for(int i = 0; i<4; i++) {
        int num = i;
        tp.enqueue([num, &task] {
            task.run(num);
        });
    }
    return 0;
}

以上就是C++ 學(xué)習(xí)筆記實(shí)戰(zhàn)寫一個簡單的線程池示例的詳細(xì)內(nèi)容,更多關(guān)于C++ 線程池的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言項(xiàng)目小學(xué)生數(shù)學(xué)考試系統(tǒng)參考

    C語言項(xiàng)目小學(xué)生數(shù)學(xué)考試系統(tǒng)參考

    今天小編就為大家分享一篇關(guān)于C語言項(xiàng)目小學(xué)生數(shù)學(xué)考試系統(tǒng)參考,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • C++ 迷宮游戲?qū)崿F(xiàn)代碼

    C++ 迷宮游戲?qū)崿F(xiàn)代碼

    這篇文章主要介紹了C++ 迷宮游戲?qū)崿F(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • shared_ptr線程安全性全面分析

    shared_ptr線程安全性全面分析

    正如boost文檔所宣稱的,boost為shared_ptr提供了與內(nèi)置類型同級別的線程安全性。這包括:1. 同一個shared_ptr對象可以被多線程同時讀取。2. 不同的shared_ptr對象可以被多線程同時修改成
    2013-09-09
  • C++調(diào)用Go方法的字符串傳遞問題及解決方案

    C++調(diào)用Go方法的字符串傳遞問題及解決方案

    這篇文章主要介紹了C++調(diào)用Go方法的字符串傳遞問題及解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • C語言實(shí)現(xiàn)小學(xué)生隨機(jī)出題測試計(jì)分

    C語言實(shí)現(xiàn)小學(xué)生隨機(jī)出題測試計(jì)分

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)小學(xué)生隨機(jī)出題測試計(jì)分,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • QT使用QFile進(jìn)行文件操作

    QT使用QFile進(jìn)行文件操作

    本文主要介紹了QT使用QFile進(jìn)行文件操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • C 語言結(jié)構(gòu)體的使用方法

    C 語言結(jié)構(gòu)體的使用方法

    這篇文章主要介紹了C 語言結(jié)構(gòu)體的使用,文章介紹了結(jié)構(gòu)體定義的多種類型,想具體了解的朋友請看下面文章的內(nèi)容
    2021-09-09
  • C語言中的字符串?dāng)?shù)據(jù)在C中的存儲方式

    C語言中的字符串?dāng)?shù)據(jù)在C中的存儲方式

    這篇文章主要介紹了C語言中的字符串?dāng)?shù)據(jù)在C中的存儲方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C語言實(shí)現(xiàn)電腦關(guān)機(jī)程序

    C語言實(shí)現(xiàn)電腦關(guān)機(jī)程序

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)電腦關(guān)機(jī)程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C語言實(shí)現(xiàn)萬年歷

    C語言實(shí)現(xiàn)萬年歷

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)萬年歷,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10

最新評論