首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C++ 線程池完整實現:基於信號量與臨界區的任務隊列設計與使用範例

     編輯:關於C語言

多線程編程能顯著提升多核 CPU 利用率。本文提供一個可復用的 C++ 線程池實現:基於 Windows 信號量同步、臨界區互斥、動態任務隊列,支持任務異常捕獲與優雅關閉。附帶 Excel 導出異步寫入的實戰範例。

核心類設計

WorkItemBase(任務抽象基類)

class WorkItemBase {
    virtual void DoWork(void* pThreadContext) = 0; // 具體任務邏輯
    virtual void Abort() = 0;                      // 池銷毀時調用
    friend class CWorkQueue;
};

CWorkQueue(線程池管理器)

  • Create(nThreads, threadDataArray):創建 N 個工作線程,每線程可傳遞私有上下文指針。
  • InsertWorkItem(WorkItemBase*):線程安全入隊,釋放信號量喚醒一線程。
  • Destroy(waitSec):等待隊列清空 → 設置退出事件 → 等待所有線程結束 → 清理資源。
  • 同步物件:Semaphore(任務計數)、Event(退出通知)、CriticalSection(隊列互斥)。

關鍵實現片段

線程主循環

unsigned long __stdcall CWorkQueue::ThreadFunc(void* pParam) {
    THREAD_CONTEXT* ctx = (THREAD_CONTEXT*)pParam;
    CWorkQueue* pQueue = ctx->pWorkQueue;
    void* pThreadData = ctx->pThreadData;

    for (;;) {
        DWORD ret = WaitForMultipleObjects(2, pQueue->m_phSyncObjects, FALSE, INFINITE);
        switch (ret - WAIT_OBJECT_0) {
            case 0: // ABORT_EVENT
                delete ctx; return 0;
            case 1: // SEMAPHORE
                WorkItemBase* item = pQueue->RemoveWorkItem();
                if (item) item->DoWork(pThreadData);
                break;
        }
    }
}

任務入隊/出隊

bool CWorkQueue::InsertWorkItem(WorkItemBase* item) {
    EnterCriticalSection(&m_CriticalSection);
    m_pWorkItemQueue->push(item);
    LeaveCriticalSection(&m_CriticalSection);
    return ReleaseSemaphore(m_phSyncObjects[SEMAPHORE_INDEX], 1, NULL);
}

WorkItemBase* CWorkQueue::RemoveWorkItem() {
    EnterCriticalSection(&m_CriticalSection);
    WorkItemBase* item = m_pWorkItemQueue->front();
    m_pWorkItemQueue->pop();
    LeaveCriticalSection(&m_CriticalSection);
    return item;
}

實戰範例:異步導出 Excel

具體任務類

class CWorkItem : public WorkItemBase {
    vector m_data;
    String m_filePath;
public:
    void SetWriteContent(const vector& data) { m_data = data; }
    void SetExcelPath(const String& path) { m_filePath = path; }
    void DoWork(void* ctx) override {
        OperateExcel op;
        String err;
        op.WriteDateToExcel(m_filePath, m_data, err);
        delete this; // 自毀
    }
    void Abort() override { delete this; }
};

使用方式

CWorkQueue pool;
pool.Create(4); // 4 條工作線程

CWorkItem* item1 = new CWorkItem();
item1->SetWriteContent(data);
item1->SetExcelPath("D:\\report1.xls");
pool.InsertWorkItem(item1);

CWorkItem* item2 = new CWorkItem();
item2->SetWriteContent(data);
item2->SetExcelPath("D:\\report2.xls");
pool.InsertWorkItem(item2);

pool.Destroy(5); // 最多等 5 秒清空隊列

設計亮點

  1. 上下文隔離:每線程可持有獨立 pThreadData(如資料庫連接、COM 初始化狀態)。
  2. 異常安全:任務內部拋出異常不會導致線程退出,池繼續運行。
  3. 優雅關閉:Destroy 先等隊列清空,再廣播退出事件,最後 Abort 清理殘留任務。
  4. 零依賴:僅依賴 Windows API + STL,無 Boost/Qt 等重型庫。

適用場景

  • IO 密集型異步任務(文件寫入、網絡請求、資料庫批量操作)。
  • 計算密集型任務需配合 SetThreadIdealProcessor 綁核優化。
  • 需精確控制併發度、任務優先級可擴展為優先級隊列。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved