日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows 临界区(CRITICAL_SECTION)的使用

發布時間:2023/12/20 windows 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows 临界区(CRITICAL_SECTION)的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

由于需要在多線程中并發操作臨界數據,為了保證臨界數據操作的完整性,Linux下使用鎖(Linux下鎖可以看我的這篇博客Linux 互斥鎖 遞歸鎖 自旋鎖 讀寫鎖),而在Windows下,使用的是臨界區。

每個線程中訪問臨界資源的那段程序稱為臨界區(Critical Section)(臨界資源是一次僅允許一個線程使用的共享資源)。每次只準許一個線程進入臨界區,進入后不允許其他線程進入。不論是硬件臨界資源,還是軟件臨界資源,多個線程必須互斥地對它進行訪問。在說臨界區之前,我們先講下同步和互斥,以理解為什么需要臨界區。

?


同步和互斥機制

  • 基本概念

同步和互斥的概念有時候很容易混淆,可以簡單地認為同步是更加宏觀角度的一種說法,互斥是沖突解決的細節方法。所謂同步就是調度者讓任務按照約定的合理的順序進行,但是當任務之間出現資源競爭,也就是競態沖突時,使用互斥的規則強制約束允許數量的任務占用資源,從而解決各個競爭狀態,實現任務的合理運行。

同步和互斥密不可分,有資料說互斥是一種特殊的同步,對此我不太理解,不過實際中想明白細節就行,文字游戲沒有意義。

簡單來說:

  • 同步與互斥機制是用于控制多個任務對某些特定資源的訪問策略
  • 同步是控制多個任務按照一定的規則或順序訪問某些共享資源
  • 互斥是控制某些共享資源在任意時刻只能允許規定數量的任務訪問
  • 角色分類

整個協調流程涉及的角色本質上只有三類:

  • 不可獨占的共享資源
  • 多個使用者
  • 調度者

調度者需要為多個運行任務制定訪問使用規則來實現穩定運行,這個調度者可以是內核、可以是應用程序,具體場景具體分析。

  • 重要術語

要很好地理解同步和互斥,就必須得搞清楚幾個重要術語:

  • 競爭冒險(race hazard)或競態條件(race condition)

最早聽說這個術語是在模電數電的課程上,門電路出現競態條件造成錯誤的結果,在計算機里面就是多個使用者同時操作共享的變量造成結果的不確定。

  • 臨界區

臨界區域critical section是指多使用者可能同時共同操作的那部分代碼,比如自加自減操作,多個線程處理時就需要對自加自減進行保護,這段代碼就是臨界區域。

?


?臨界區(Critical Section)

Linux下有遞歸鎖,遞歸鎖是同一個線程在不解鎖的情況下,可以多次獲取鎖定同一個遞歸鎖,而且不會產生死鎖。windows下的互斥量和臨界區(關鍵段)默認支持遞歸鎖。

  • void InitializeCriticalSection(? LPCRITICAL_SECTION?lpCriticalSection);初始化一個臨界區對象
  • void DeleteCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);刪除臨界區對象釋放由該對象使用的所有系統資源

  • void EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection );//進入臨界區,相當于Linux下lock

  • void LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection );//刪除臨界區,相當于Linux下unlock

#include <Windows.h> #include <iostream> #include <string> ? int counter = 0; ? // 定義一個臨界區變量 CRITICAL_SECTION g_cs; ? void doit(void* arg) {int i, val;for (i=0; i<5000; i++){// 臨界區默認支持遞歸鎖,所以這里在臨界區里再次進入臨界區也沒關系,正常使用調用一次即可EnterCriticalSection(&g_cs);EnterCriticalSection(&g_cs); ?val = counter;printf("thread %d : %d\n", int(arg), val+1);counter = val + 1; ?// 離開臨界區LeaveCriticalSection(&g_cs);LeaveCriticalSection(&g_cs);} } ? int main(int argc, char*argv[]) {// 初始化臨界區InitializeCriticalSection(&g_cs); ?HANDLE hThread1 = CreateThread(NULL,0, (LPTHREAD_START_ROUTINE)doit, (void*)1, 0, NULL);HANDLE hTrehad2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)doit, (void*)2, 0, NULL); ?WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hTrehad2, INFINITE); ?// 刪除臨界區DeleteCriticalSection(&g_cs); ?return 0; }

使用臨界區加1次鎖和2次鎖,均可以正確的輸出1~10000。

?

總結

以上是生活随笔為你收集整理的Windows 临界区(CRITICAL_SECTION)的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。