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

執行緒與進程間通訊、同步機制全解析

     編輯:關於VC++

多執行緒與多進程程式設計中,資料交換與同步控制是核心課題。本文系統整理 Windows 平台下的主流 IPC(進程間通訊)與同步原語,並提供 VC++ 與 .NET 兩套實作範例,供開發者快速查閱與選型。

一、通訊方式總覽

類別機制適用場景跨進程
共享記憶體全域變數 / CreateFileMapping + MapViewOfFile高速、大量資料交換是
核心物件命名管道、匿名管道父子進程、本機高可靠傳輸是(命名管道)
訊息機制視窗訊息 (PostMessage/SendMessage)UI 執行緒通知、簡單命令傳遞否(需相同桌面)
網路通訊Socket (TCP/UDP)跨機器、異構系統整合是
參數傳遞命令列參數、環境變數、CreateThread 的 lpParameter啟動階段設定部分

二、執行緒建立與終止

VC++ (Win32 API)

DWORD WINAPI ThreadProc(LPVOID lParam);
HANDLE hThread = CreateThread(NULL, 0, ThreadProc, lParam, 0, &dwThreadId);
// 等待結束
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
// 取得退出碼
GetExitCodeThread(hThread, &exitCode);
// 強制終止(極不推薦)
TerminateThread(hThread, 0);

.NET (C#)

using System.Threading;
Thread th = new Thread(new ParameterizedThreadStart(ThreadProc));
th.IsBackground = true; // 主程式結束時自動終止
th.Start(lParam);
th.Join(); // 等待結束
th.Abort(); // 強制中止(慎用)

三、進程建立與管理

VC++

STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi;
BOOL bRet = CreateProcess(
    pFileName, pArgs, NULL, NULL, FALSE,
    0, pEnv, NULL, &si, &pi);
// 同步等待
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
GetExitCodeProcess(pi.hProcess, &exitCode);

.NET

using System.Diagnostics;
Process p = new Process();
p.StartInfo.FileName = ...;
p.StartInfo.Arguments = ...;
p.Start();
p.WaitForExit();
int exitCode = p.ExitCode;
p.Kill(); // 強制終止

四、同步原語深度解析

1. 臨界區 - 輕量級、進程內

// VC++
CRITICAL_SECTION cs;
InitializeCriticalSection(&cs); // 或 InitializeCriticalSectionAndSpinCount(&cs, 2000)
EnterCriticalSection(&cs);
// ... 受保護區段 ...
LeaveCriticalSection(&cs);
DeleteCriticalSection(&cs);

// .NET
lock (syncObj) { ... }
// 或
Monitor.Enter(syncObj);
try { ... } finally { Monitor.Exit(syncObj); }

注意:跨進程需置於共享記憶體;優先使用 RAII 包裝類別防止忘記釋放。

2. 互斥體 - 核心物件、跨進程、可檢測遺棄

// VC++
HANDLE hMutex = CreateMutex(NULL, FALSE, L"Global\\MyMutex"); // 命名互斥體
WaitForSingleObject(hMutex, INFINITE); // 返回 WAIT_ABANDONED 表示前擁有者異常終止
ReleaseMutex(hMutex);
CloseHandle(hMutex);

// .NET
using System.Threading;
Mutex m = new Mutex(false, "Global\\MyMutex");
m.WaitOne();
m.ReleaseMutex();

3. 信號量 - 計數型、控制並發存取數

// VC++
HANDLE hSem = CreateSemaphore(NULL, 1, 5, L"Global\\MySem"); // 初始 1,最大 5
WaitForSingleObject(hSem, INFINITE); // 計數 -1
ReleaseSemaphore(hSem, 1, NULL); // 計數 +1

// .NET
Semaphore sem = new Semaphore(1, 5, "Global\\MySem");
sem.WaitOne();
sem.Release(1);

進程終止時信號量不會自動釋放,需謹慎設計。

4. 事件 - 訊號通知、自動/手動重設

// VC++ 事件控制執行緒迴圈(優於輪詢旗標)
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // 手動重設
// Worker
while (TRUE) {
    DWORD dw = WaitForSingleObject(hEvent, 1);
    if (dw == WAIT_OBJECT_0) break;
    DoWork();
}
// Stopper
SetEvent(hEvent);
WaitForSingleObject(hThread, INFINITE);

5. 原子操作 - 硬體級、極低開銷

適用於引用計數、簡單計數器。VC++ 使用 InterlockedIncrement 等;.NET 使用 System.Threading.Interlocked 類別。僅鎖定資料而非程式碼區段。

6. 自旋鎖 - 使用者態、適合極短區段、多核心

單核心下無意義;長區段會導致 CPU 100% 忙等待。Windows 提供 SRWLOCK (Vista+) 兼具自旋與核心等待優勢。

五、死鎖預防指南

  • 鎖定順序固定化(避免循環等待)
  • 縮小臨界區範圍(非關鍵碼勿入鎖)
  • 嚴禁在鎖內呼叫 SendMessage、回呼函式或阻塞性 API
  • 使用 try/finally 或 RAII 確保釋放
  • 避免 TerminateThread/Process 導致鎖永不釋放

六、選型建議

  • 進程內、高頻、短區段 → Critical Section / SRWLOCK
  • 跨進程、單一存取 → Mutex
  • 資源池、限制並發數 → Semaphore
  • 狀態通知、生產者消費者 → Event
  • 單一整數原子增減 → Interlocked

掌握這些機制的特性與適用邊界,是撰寫高效、穩定並發程式的基石。

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