Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學

Linux 線程池 C++ 實現:任務隊列、同步機制與 RAII 封裝

編輯:Linux 系統常見問題解答

設計目標

  • 預創建固定數量線程,避免頻繁創建/銷毀開銷。
  • 任務隊列線程安全,支持動態提交。
  • 工作線程空閒/忙碌狀態跟蹤,優雅關閉。

核心數據結構

// 抽象任務基類class CTask {protected:    std::string m_strTaskName;    void* m_ptrData;  // 業務數據指針public:    CTask() : m_ptrData(nullptr) {}    explicit CTask(const std::string& name) : m_strTaskName(name), m_ptrData(nullptr) {}    virtual ~CTask() {}    virtual int Run() = 0;  // 純虛函數,子類實現業務邏輯    void SetData(void* data) { m_ptrData = data; }    const std::string& GetName() const { return m_strTaskName; }};

線程池類

class CThreadPool {private:    std::vector m_vecTaskList;      // 任務隊列    std::vector m_vecIdleThread; // 空閒線程 ID    std::vector m_vecBusyThread; // 忙碌線程 ID    pthread_mutex_t m_mutex;                // 隊列/狀態鎖    pthread_cond_t m_cond;                  // 條件變量: 有任務/線程可用    int m_iThreadNum;                       // 線程池大小    bool m_bShutdown;                       // 關閉標誌    // 靜態線程入口函數    static void* ThreadFunc(void* arg);    // 狀態遷移輔助    int MoveToIdle(pthread_t tid);    int MoveToBusy(pthread_t tid);    int CreateThreads();public:    explicit CThreadPool(int threadNum);    ~CThreadPool();    int AddTask(CTask* task);  // 提交任務, 喚醒一個空閒線程    int StopAll();             // 停止所有線程, 清理資源};

關鍵實現細節

線程啟動

int CThreadPool::CreateThreads() {    for (int i = 0; i < m_iThreadNum; ++i) {        pthread_t tid;        if (pthread_create(&tid, nullptr, ThreadFunc, this) != 0) return -1;        m_vecIdleThread.push_back(tid);    }    return 0;}

工作線程主循環

void* CThreadPool::ThreadFunc(void* arg) {    CThreadPool* pool = static_cast(arg);    while (true) {        CTask* task = nullptr;        // 1. 獲取任務 (加鎖等待)        pthread_mutex_lock(&pool->m_mutex);        while (pool->m_vecTaskList.empty() && !pool->m_bShutdown) {            pthread_cond_wait(&pool->m_cond, &pool->m_mutex);        }        if (pool->m_bShutdown) {            pthread_mutex_unlock(&pool->m_mutex);            break;        }        task = pool->m_vecTaskList.front();        pool->m_vecTaskList.erase(pool->m_vecTaskList.begin());        pool->MoveToBusy(pthread_self());        pthread_mutex_unlock(&pool->m_mutex);        // 2. 執行任務 (無鎖, 並發)        if (task) {            task->Run();            delete task;  // 池負責釋放任務對象        }        // 3. 歸還空閒        pthread_mutex_lock(&pool->m_mutex);        pool->MoveToIdle(pthread_self());        pthread_mutex_unlock(&pool->m_mutex);    }    return nullptr;}

提交任務

int CThreadPool::AddTask(CTask* task) {    if (!task) return -1;    pthread_mutex_lock(&m_mutex);    if (m_bShutdown) {        pthread_mutex_unlock(&m_mutex);        return -1;    }    m_vecTaskList.push_back(task);    pthread_cond_signal(&m_cond);  // 喚醒一個等待線程    pthread_mutex_unlock(&m_mutex);    return 0;}

優雅關閉

int CThreadPool::StopAll() {    pthread_mutex_lock(&m_mutex);    m_bShutdown = true;    pthread_cond_broadcast(&m_cond); // 喚醒所有等待線程    pthread_mutex_unlock(&m_mutex);    for (pthread_t tid : m_vecIdleThread) pthread_join(tid, nullptr);    for (pthread_t tid : m_vecBusyThread) pthread_join(tid, nullptr);    m_vecIdleThread.clear(); m_vecBusyThread.clear();    // 清理殘留任務    for (auto* t : m_vecTaskList) delete t;    m_vecTaskList.clear();    return 0;}

使用示例

class MyTask : public CTask {public:    int Run() override {        int* data = static_cast(m_ptrData);        std::cout << "Processing " << *data << " on thread " << pthread_self() << std::endl;        return 0;    }};int main() {    CThreadPool pool(4);    for (int i = 0; i < 10; ++i) {        int* p = new int(i);        MyTask* task = new MyTask();        task->SetData(p);        pool.AddTask(task);    }    sleep(2);  // 等待完成    pool.StopAll();    return 0;}

現代 C++ 改進建議 (C++11/17)

  • 用 std::thread、std::mutex、std::condition_variable 替代 pthread。
  • 任務類型擦除:std::function + std::packaged_task 支持任意可調用對象與 future 返回值。
  • 智能指針管理任務生命週期:std::unique_ptr 或 std::shared_ptr。
  • 工作盜演算法 (std::deque + 雙端鎖) 提升多核負載均衡。
  • 參考開源成熟庫:progschj/ThreadPool (單頭文件)、bshoshany/thread-pool (功能豐富)。
Copyright © Windows教程網 All Rights Reserved