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

跨平台用戶態自旋鎖實現:Windows VC 與 Linux GCC 統一介面

     編輯:關於C語言

適用場景

自旋鎖適合競爭輕微、臨界區極短的情況(驅動、內核常用)。本文提供純用戶態、跨平台(Win32+VC / Linux+GCC≥4.1.2)的 C 介面實現。

介面設計

typedef struct {
    volatile long flag_;       // 鎖標誌位(或指向外部標誌)
    volatile long* spin_;      // 實際自旋變數位址
} spin_lock_t;

void spin_init(spin_lock_t* lock, long* flag);   // flag=NULL 時用內部 flag_
void spin_lock(spin_lock_t* lock);               // 阻塞式獲取
int  spin_trylock(spin_lock_t* lock);            // 非阻塞嘗試
void spin_unlock(spin_lock_t* lock);             // 釋放
int  spin_is_lock(spin_lock_t* lock);            // 查詢狀態

核心原子操作映射表

語意Windows (VC)Linux (GCC ≥4.1.2)
原子交換InterlockedExchange__sync_lock_test_and_set
原子或後取舊值InterlockedOr (Vista+)__sync_fetch_and_or
原子加後取新值InterlockedExchangeAdd__sync_add_and_fetch
原子與後取新值InterlockedAnd (Vista+)__sync_and_and_fetch
CPU 讓出Sleep(1)sched_yield()

關鍵實現片段

void spin_lock(spin_lock_t* lock) {
#ifdef _MSC_VER
    for (; 0 != InterlockedExchange((volatile long*)lock->spin_, 1); )
        Sleep(1);
#elif defined(__GNUC__)
    for (; 0 != __sync_fetch_and_or(lock->spin_, 1); )
        sched_yield();
#endif
}

void spin_unlock(spin_lock_t* lock) {
#ifdef _MSC_VER
    InterlockedExchange((volatile long*)lock->spin_, 0);
#elif defined(__GNUC__)
    __sync_and_and_fetch(lock->spin_, 0);
#endif
}

設計細節

  • spin_ 可指向外部標誌,支援多鎖共享單一旗標(如陣列鎖);
  • volatile 防止編譯器優化掉自旋讀寫;
  • GCC 版本檢查確保內建原子函數可用;
  • 無 C++ 依賴,純 C 介面,嵌入式專案亦可直接使用。

效能提示

自旋等待時呼叫 Sleep(1) / sched_yield() 釋放時間片,避免佔滿 CPU。若臨界區極短(幾十指令),可改為 _mm_pause() / __builtin_ia32_pause() 總線鎖優化。

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