首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

多線程中 Sleep(1000) 掩蓋同步 Bug:移除 Sleep 需加鎖/事件等待

     編輯:程式設計綜合問答

問題代碼片段

_beginthread(ThreadFunc1, 0, NULL);
_beginthread(ThreadFunc2, 0, NULL);
Sleep(1000);  // 硬編碼等待,掩蓋了同步缺失
sum = sum1 + sum2;

現象解釋

Sleep(1000) 偶然給了兩個工作線程足夠時間跑完,主線程才繼續執行求和。**這不是同步,是賭時間**。一旦線程執行時間超過 1 秒(數據量大、CPU 繁忙、鎖爭用),主線程就會讀取未完成的 sum1/sum2,結果錯誤甚至崩潰。

正確同步方案

方案一:事件對象

HANDLE hEvent[2];
hEvent[0] = CreateEvent(NULL, TRUE, FALSE, NULL);
hEvent[1] = CreateEvent(NULL, TRUE, FALSE, NULL);

_beginthread(ThreadFunc1, 0, (void*)hEvent[0]);
_beginthread(ThreadFunc2, 0, (void*)hEvent[1]);

WaitForMultipleObjects(2, hEvent, TRUE, INFINITE);  // 等待兩個事件均觸發
sum = sum1 + sum2;
CloseHandle(hEvent[0]); CloseHandle(hEvent[1]);

線程函數結束前 SetEvent((HANDLE)param);。

方案二:計數器 + 臨界區

long completed = 0;
CRITICAL_SECTION cs;
InitializeCriticalSection(&cs);

auto finish = [&]() {
    EnterCriticalSection(&cs);
    if (++completed == 2) SetEvent(hMainEvent);
    LeaveCriticalSection(&cs);
};

方案三:C++11 std::thread + std::future(現代寫法)

std::future<int> f1 = std::async(std::launch::async, []{ return calcPart1(); });
std::future<int> f2 = std::async(std::launch::async, []{ return calcPart2(); });
sum = f1.get() + f2.get();  // get() 內部阻塞等待完成

關鍵點

  • Sleep 不是同步原語,不可用於協調線程完成順序。
  • 用 **事件、條件變量、future、信號量、屏障** 等顯式同步機制。
  • 共享變量 sum1/sum2 需原子操作或鎖保護,避免數據競爭。

總結

代碼中 Sleep(1000) 掩蓋了缺失的線程同步。移除 Sleep 後必須引入 **顯式等待機制**(事件/等待句柄/future),確保主線程在所有工作線程**確實完成**後再聚合結果。這是多線程編程的基本功。

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