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

MFC 線程同步:使用 CSemaphore 信號量實現資源計數保護

     編輯:關於VC++

除了臨界區與互斥體,CSemaphore 信號量提供更靈活的同步機制:允許指定最大同時存取共享資源的線程數,類似作業系統 PV 操作。

核心原理

信號量內部維護一個計數器。線程存取資源時計數遞減,歸零時阻塞後續線程;線程釋放資源時計數遞增,喚醒等待線程。

信號量示意圖

建立與使用

// 建立:初始計數 2,最大計數 2(允許 2 線程並發存取)
CSemaphore Semaphore(2, 2);
// 或動態建立
CSemaphore* pSemaphore = new CSemaphore(2, 2);

// 使用 CSingleLock 管理鎖定/解鎖
CSingleLock SingleLock(pSemaphore);
SingleLock.Lock();   // 計數 -1,若為 0 則阻塞
// ... 存取共享資源 ...
SingleLock.Unlock(); // 計數 +1,喚醒等待線程

完整範例:共享資源類與多線程測試

共享資源類

#include "afxmt.h"

class CSharedResource
{
private:
    CSemaphore* m_pSemaphore;
public:
    CSharedResource() { m_pSemaphore = new CSemaphore(2, 2); }
    ~CSharedResource() { delete m_pSemaphore; }

    void AccessResource()
    {
        CSingleLock lock(m_pSemaphore);
        lock.Lock();
        // ... 資源存取操作 ...
        Sleep(1000); // 模擬耗時操作
        lock.Unlock();
    }
};

CSharedResource SharedResource; // 全域實例

三個測試線程

UINT Thread_Proc1(LPVOID param)
{
    SharedResource.AccessResource();
    ::MessageBox((HWND)param, "Thread #1 accessed!", "Thread Proc1", MB_OK);
    return 0;
}

UINT Thread_Proc2(LPVOID param)
{
    SharedResource.AccessResource();
    ::MessageBox((HWND)param, "Thread #2 accessed!", "Thread Proc2", MB_OK);
    return 0;
}

UINT Thread_Proc3(LPVOID param)
{
    SharedResource.AccessResource();
    ::MessageBox((HWND)param, "Thread #3 accessed!", "Thread Proc3", MB_OK);
    return 0;
}

啟動線程

HWND hWnd = GetSafeHwnd();
AfxBeginThread(Thread_Proc1, hWnd);
AfxBeginThread(Thread_Proc2, hWnd);
AfxBeginThread(Thread_Proc3, hWnd);

執行結果

前兩個線程取得信號量並存取資源,第三個線程阻塞等待。直到前兩者釋放,第三者才能進入。有效實現了多線程對共享資源的計數保護與資料同步。

本文為筆者多線程學習筆記,供參考交流。配套原始碼供下載。

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