1. 程式人生 > >線程同步方法

線程同步方法

gpo 設置 word targe dex nand ini 周期 dsp

一 windows下的方法

  1 原子訪問系列函數(優點是相對於其他的方案, 執行效率高)

    (1)原子加減法

       LONG __cdecl InterlockedExchangeAdd(LONG volatile*Addend,LONG Value);

      LONGLONG __cdecl InterlockedExchangeAdd64(LONGLONG volatile*Addend,LONGLONG Value);

      分別針對32位/64位有符號整數進行原子加法的操作, 當Value為負數時, 做原子減法,返回初始值

    (2) 原子替換

      LONG __cdecl InterlockedExchange(LONG volatile *Target,LONG Value);//32位

      SHORT __cdecl InterlockedExchange16(SHORT volatile *Target,SHORT Value);//16位

      LONG LONG __cdecl InterlockedExchange64(LONG LONG volatile *Target,LONGLONG Value);//64位

      PVOID __cdecl InterlockedExchangePointer(PVOID volatile *Target,PVOID Value); //這個本意是用來替換指針變量的, 其實也可以用來替換普通的變量, 此時PVOID可以理解成VOID

      把第一個參數的指向的值替換為第二個參數, 並返回替換之前的值, 其中最後一個是自適應的函數, 在32位系統下替換32位值, 64位替換64位值, 返回的是替換之前的值

    (3)原子比較替換

      LONG __cdecl InterlockedCompareExchange(LONG volatile *Destination, LONG Exchange,LONG Comparand);

      LONGLONG __cdecl InterlockedCompareExchange64(LONGLONG volatile *Destination, LONGLONG Exchange,LONGLONG Comparand);

      PVOID __cdecl InterlockedCompareExchangePointer(PVOID volatile *Destination, PVOID Exchange,PVOID Comparand);

      先比較再替換, 如果不同則不替換

  2 使用關鍵段(優點: 內部會使用1中的函數, 運行效率比較高; 缺點: 不能跨進程使用)

    (1)初始化函數

    CRITICAL_SECTION cs;

    void __stdcall InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

    BOOL WINAPI InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount);

    兩個的區別是第二個在使用關鍵段的同時也使用自旋鎖, 當某個要進入臨界區的線程被判定為需要等待時, 先使用自旋鎖方式進行等待, 然後再進入等待狀態.

    使用場景是如果等待的時間比較短, 這種效率會更高,因為使線程進入等待狀態需要使用大約1000個cpu周期. 第二個參數一般設置為4000以下

    

    (2)進入離開臨界區

    void WINAPI EnterCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);

    void WINAPI LeaveCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);

    (3)刪除結構體

    void WINAPI DeleteCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);

     

    

線程同步方法