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

《編程之美》1.10 雙線程下載:生產者-消費者模式實現

     編輯:C++ 入門

問題背景

網絡下載文件寫入硬碟。串行方式:下一塊 → 寫一塊,效率低。
改進:雙線程並行,緩衝區 + 信號量同步。

架構設計

  • 下載線程:緩衝區有空位 → 下載一塊 → 通知寫入線程
  • 寫入線程:緩衝區有數據 → 寫入硬碟 → 通知下載線程
  • 環形緩衝區:固定大小陣列模擬隊列
  • 兩個信號量:
    • ForDownload:空閒槽位數 (初始 MAX)
    • ForWrite:可寫數據塊數 (初始 0)

同步邏輯

// 下載線程
while (true) {
    ForDownload.wait();           // 等待空位
    isDone = GetBlockFromNet(buf[in_idx]);
    in_idx = (in_idx + 1) % MAX;
    ForWrite.signal();            // 通知有數據
    if (isDone) break;
}

// 寫入線程
while (true) {
    ForWrite.wait();              // 等待數據
    WriteBlockToDisk(buf[out_idx]);
    out_idx = (out_idx + 1) % MAX;
    ForDownload.signal();         // 釋放空位
    if (isDone && in_idx == out_idx) break; // 全部寫完
}

完整 C++ 框架代碼

#define MAX_COUNT 1000
Block g_Buffer[MAX_COUNT];
Thread g_Download(ProcA), g_Write(ProcB);
Semaphore ForDownload(MAX_COUNT, MAX_COUNT);
Semaphore ForWrite(0, MAX_COUNT);
bool isDone = false;
int in_idx = 0, out_idx = 0;

void ProcA() { /* 下載邏輯 */ }
void ProcB() { /* 寫入邏輯 */ }

int main() {
    g_Download.Start();
    g_Write.Start();
    // 等待線程結束...
    return 0;
}

關鍵點解析

  1. 信號量而非互斥鎖:允許並行,只同步「空位/數據」計數
  2. 環形緩衝區:in_idx 生產者指針,out_idx 消費者指針
  3. 終止條件:下載結束 isDone 且緩衝區清空 in_idx == out_idx
  4. API 抽象:GetBlockFromNet, WriteBlockToDisk 隔離業務邏輯

擴展方向

  • 多生產者/多消費者:信號量天然支援
  • 優先級緩衝區:優先級隊列替代環形陣列
  • 異步 I/O:Overlapped I/O / epoll 替代阻塞寫入

參考資源

  • 《編程之美》第 1 章 第 10 題
  • 生產者-消費者模式經典實現
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved