C++線程池實現

一、線程池簡介

一個線程池是由若干在等待任務的線程組成的線程池,當請求到來時,將任務分配給其中一個空閑線程執行;當任務執行完畢後,線程並沒有結束,而是繼續等待下一個任務。在伺服器程序中,很多請求都是短時間的,大部分處理時間卻是在等待數據的IO操作上,因此線程池可以極大地提高伺服器的並發能力和響應速度。

二、C++線程池實現原理

1. 首先,我們需要引入常見的C++並發庫,如<mutex><thread>等。

    #include <mutex>
    #include <thread>

2. 聲明一個線程池類ThreadPool。

    class ThreadPool {
    public:
        //聲明構造函數、析構函數、添加任務函數等
    private:
        //聲明任務隊列、線程池等變數
    };

3. 在構造函數中,初始化線程池和任務隊列。

    ThreadPool::ThreadPool(int size) {
        for (int i = 0; i < size; i++) {
            //創建線程,將線程函數設置為work函數
            //存儲線程到線程池中
            //設置線程為detachable,即自動釋放
        }
    }

4. 添加任務函數需要將任務加入任務隊列,喚醒等待線程,通知有新的任務需要執行。

    template <class F, class... Args>
    auto ThreadPool::enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> {
        //獲取任務返回值類型
        using return_type = typename std::result_of<F(Args...)>::type;
        //將任務和返回值類型build成packaged_task
        auto task = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
        //使用future獲取非同步返回值
        std::future<return_type> res = task->get_future();
        {
            //加鎖保證對任務隊列的操作是原子的
            std::unique_lock<std::mutex> lock(queue_mutex);
            //將任務加入隊列
            tasks.emplace([task]() { (*task)(); });
        }
        //喚醒等待線程,通知有新的任務需要執行
        condition.notify_one();
        return res;
    }

三、C++線程池實現代碼示例

下面是ThreadPool類的完整代碼示例:

#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>

class ThreadPool {
public:
    //構造函數,初始化線程池和任務隊列
    ThreadPool(int size) {
        for (int i = 0; i < size; i++) {
            threads.emplace_back(std::thread(&ThreadPool::work, this));
            threads.back().detach();
        }
    }

    //析構函數,回收線程池
    ~ThreadPool() {}

    //添加任務函數,將任務加入任務隊列,喚醒等待線程,通知有新的任務需要執行
    template <class F, class... Args>
    auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> {
        //獲取任務返回值類型
        using return_type = typename std::result_of<F(Args...)>::type;
        //將任務和返回值類型build成packaged_task
        auto task = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
        //使用future獲取非同步返回值
        std::future<return_type> res = task->get_future();
        {
            //加鎖保證對任務隊列的操作是原子的
            std::unique_lock<std::mutex> lock(queue_mutex);
            //將任務加入隊列
            tasks.emplace([task]() { (*task)(); });
        }
        //喚醒等待線程,通知有新的任務需要執行
        condition.notify_one();
        return res;
    }

private:
    //執行任務函數
    void work() {
        while (true) {
            std::function<void()> task;
            {
                //加鎖保證對任務隊列的操作是原子的
                std::unique_lock<std::mutex> lock(queue_mutex);
                //等待任務隊列非空
                condition.wait(lock, [this]() { return !tasks.empty(); });
                //取出隊列中的一個任務
                task = std::move(tasks.front());
                tasks.pop();
            }
            //執行任務
            task();
        }
    }

private:
    //線程池
    std::vector<std::thread> threads;
    //任務隊列
    std::queue<std::function<void()>> tasks;
    //隊列鎖
    std::mutex queue_mutex;
    //任務隊列非空條件變數
    std::condition_variable condition;
}

四、線程池實現應用場景

線程池適用於很多需要處理大量短時間任務的場景,比如網路伺服器、圖像處理、視頻處理等。一些大型框架,如Web伺服器或消息匯流排系統,會使用線程池來處理並發請求,這樣可以大大提高響應速度和擴展能力。

五、總結

通過C++線程池實現,我們可以實現多線程任務的快速處理,提高系統的並發處理能力和響應速度,並且保證線程的可控性、執行流程的正確性和程序的高效性。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/198642.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-04 10:27
下一篇 2024-12-04 10:27

相關推薦

  • Python線程等待指南

    本文將從多個方面詳細講解Python線程等待的相關知識。 一、等待線程結束 在多線程編程中,經常需要等待線程執行完畢再進行下一步操作。可以使用join()方法實現等待線程執行完畢再…

    編程 2025-04-29
  • Python兩個線程交替列印1到100

    這篇文章的主題是關於Python多線程的應用。我們將會通過實際的代碼,學習如何使用Python兩個線程交替列印1到100。 一、創建線程 在Python中,我們可以使用Thread…

    編程 2025-04-28
  • ROS線程發布消息異常解決方法

    針對ROS線程發布消息異常問題,我們可以從以下幾個方面進行分析和解決。 一、檢查ROS代碼是否正確 首先,我們需要檢查ROS代碼是否正確。可能會出現的問題包括: 是否正確初始化RO…

    編程 2025-04-28
  • Python線程池並發爬蟲

    Python線程池並發爬蟲是實現多線程爬取數據的常用技術之一,可以在一定程度上提高爬取效率和數據處理能力。本文將從多個方面對Python線程池並發爬蟲做詳細的闡述,包括線程池的實現…

    編程 2025-04-27
  • 線程池中的一個線程異常了會被怎麼處理

    本文將從以下幾個方面對線程池中的一個線程異常了會被怎麼處理進行詳細闡述:異常的類型、如何捕獲異常、異常的處理方式。 一、異常的類型 在線程池中,可以出現多種類型的異常,例如線程執行…

    編程 2025-04-27
  • 線程池的七個參數

    在多線程編程中,線程池是一種非常重要的編程模型,可以解決線程創建銷毀的開銷問題,提高程序的效率。在使用線程池時,需要對其七個參數進行配置,以達到最佳性能。下面將從多個方面詳細闡述線…

    編程 2025-04-25
  • Java DelayQueue:實現延遲任務的線程安全隊列

    一、DelayQueue的概述 Java的DelayQueue 是一個阻塞隊列隊列,主要用來實現對延遲任務的調度,也就是在指定的時間之後才能夠取出任務來執行。該隊列中保存的元素都必…

    編程 2025-04-23
  • 瀏覽器線程——從多個方面深入探討

    一、瀏覽器線程的概念 瀏覽器線程是指瀏覽器中用於處理不同任務的線程。默認情況下,每個標籤頁都會有一個獨立的進程,每個進程再包含多個線程,這些線程通過協同工作來完成瀏覽器的各項任務。…

    編程 2025-04-23
  • JMeter線程組詳解

    一、線程組簡介 JMeter作為一個負載測試工具,線程組是JMeter中非常重要的一個概念,它被用來模擬請求的發送。 簡單來說,JMeter通過線程組來同時模擬多個用戶對被測試的W…

    編程 2025-04-23
  • Java線程安全的集合

    Java的集合框架是廣泛使用的標準庫之一,它被設計為高效、靈活和安全。在多線程環境中,線程安全的集合至關重要,因為多個線程同時對同一個集合進行讀寫操作可能會導致數據的不一致和線程安…

    編程 2025-04-22

發表回復

登錄後才能評論