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

C++Builder 多執行緒程式設計技術深度解析:從同步機制到生產者-消費者實戰

     編輯:關於C++

一、為什麼需要多執行緒?

在 Windows 環境下,多執行緒能顯著提升應用程式回應性與資源利用率:

  1. MDI 架構:每個文件視窗獨立執行緒處理通訊、計算,避免主介面凍結。
  2. 多核心 CPU:Windows 以執行緒為排程單位,單一執行緒只能佔用一核心;多執行緒可並行跑滿所有核心。
  3. 背景作業:耗時運算(重算、檔案 I/O、格式化)放入背景執行緒,前景維持流暢互動。

二、同步核心概念

多執行緒共享記憶體空間,同步是指協調執行緒存取共享資料,避免競爭條件。Win32 以時間片輪轉執行緒,無法預測中斷點,因此必須引入同步物件。

經典同步問題包括:生產者-消費者、讀者-寫者、哲學家進餐。本文以生產者-消費者為例實作。

三、C++Builder 多執行緒基礎:TThread 類別

VCL 封裝 Win32 Thread API 為 TThread,簡化開發。主要屬性與方法:

屬性/方法用途
Priority執行緒優先權
Suspended是否暫停
Terminated標記請求結束
ThreadID系統唯一識別碼
Synchronize(TThreadMethod)將呼叫封送至主 VCL 執行緒,安全存取 UI
WaitFor()阻塞直到執行緒結束
Resume()/Suspend()喚醒/暫停(成對使用)

四、執行緒協調三大機制

1. 避免同時存取共享資源

  • 內建鎖定:如 TCanvas::Lock()/Unlock()。
  • 臨界區:TCriticalSection 全域實例,Acquire()/Release() 互斥進入。
  • 多讀單寫同步器:TMultiReadExclusiveWriteSynchronizer,適合「頻繁讀、少量寫」場景,BeginRead/EndRead、BeginWrite/EndWrite。
  • Synchronize 方法:將存取 VCL 的程式碼包裝為無參數函式,傳給 Synchronize(),由主執行緒在安全時機執行。

2. 等待其他執行緒

  • WaitFor():等待特定執行緒完全結束。
  • 事件物件:TEvent 全域實例,SetEvent() 發送訊號,ResetEvent() 清除。適用於「等待任務完成」而非「等待執行緒結束」。

五、實戰:生產者-消費者完整實作

場景:兩個生產者執行緒、一個消費者執行緒,共享大小為 5 的緩衝區(整數陣列)。使用 TCriticalSection 保護緩衝區索引,兩個 TEvent(BeginProduce、BeginConsume)協調生產/消費節奏。

執行畫面:生產者-消費者執行畫面

生產者執行緒 Execute()

void __fastcall TProducerThread::Execute() {
    int i = 0, j;
    while (i < 100) { // 每個生產者產出 100 個項目
        Sleep(1000); // 延遲以利觀察
        if (Form1->buffer_size > 0)
            Form1->BeginConsume->SetEvent(); // 通知消費者

        Form1->ProduceGuard->Acquire(); // 進入臨界區
        i++;
        Form1->StrResult = IntToStr(i);
        j = Form1->buffer_size;
        Form1->Product[j] = i;
        Form1->buffer_size++;
        Synchronize(&ShowResult); // 刷新 UI
        Form1->BeginConsume->SetEvent();

        if (Form1->buffer_size == 5) // 緩衝區滿,等待消費者騰空
            Form1->BeginProduce->WaitFor(INFINITE);
        Sleep(1000);
        Form1->ProduceGuard->Release(); // 離開臨界區
    }
    // 收尾:喚醒消費者處理剩餘項目
    while (Form1->buffer_size > 0)
        Form1->BeginConsume->SetEvent();
}

消費者執行緒 Execute()

void __fastcall TConsumerThread::Execute() {
    for (int i = 0; i < 200; i++) { // 總共消費 200 個(兩生產者各 100)
        Sleep(100);
        Form1->BeginConsume->WaitFor(INFINITE); // 等待生產者通知
        int j = Form1->buffer_size - 1;
        Form1->StrResult = IntToStr(Form1->Product[j]);
        Form1->buffer_size--;
        Synchronize(&ShowResult); // 刷新 UI
        if (Form1->buffer_size == 4) // 緩衝區不再滿,喚醒生產者
            Form1->BeginProduce->SetEvent();
        Sleep(100);
    }
}

六、關鍵設計重點總結

  1. 緩衝區保護:TCriticalSection ProduceGuard 確保 buffer_size 與 Product[] 讀寫原子性。
  2. 條件同步:BeginProduce、BeginConsume 事件分別對應「緩衝區非滿」、「緩衝區非空」條件。
  3. UI 安全更新:所有介面操作透過 Synchronize() 封送至主執行緒。
  4. 優雅結束:生產者結束前清空緩衝區並通知消費者,避免死結。

結語

多執行緒程式設計的核心在於識別共享資源、選擇適當同步原語、設計無死結的協議。C++Builder 的 TThread、TCriticalSection、TEvent 提供了完整的工具箱,配合 Synchronize() 機制,讓開發者能專注於業務邏輯而非底層 API 細節。生產者-消費者模式更是高併發系統(訊息佇列、任務調度、資料管線)的基石,掌握其實作細節將受益無窮。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved