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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用户模式下的线程同步

發布時間:2025/3/15 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用户模式下的线程同步 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在以下兩種基本情況下,線程之間需要相互通信

1.需要讓多個線程同時訪問一個共享資源,同時不能破壞資源的完整性

2.一個線程需要通知其他線程某項任務已經完成。

原子訪問相關的內容就直接略過了,因為感覺實際使用的過程中并不多。

下面直接開始說一下關鍵段,它在執行之前需要獨占對一些共享資源的訪問權。這種方式可以讓多行代碼以原子方式來對資源進行操控。這里的原子方式,指的是代碼知道除了當前線程之外,沒有其他任何線程會同時訪問該資源。在當前線程離開關鍵段之前,系統是不會去調度任何想要訪問同一資源的其他線程的。

一般是EnterCriticalSection和LeaveCriticalScetion配對使用,需要先創建一個CRITICAL_SECTION結構。

這結構一般都是作為全局變量來使用,也可以作為局部變量來分配或者堆中,另外作為類的一個私有字段還分配也是很常見的。

在使用CRITICAL_SECTION的時候,只有兩個必要條件,第一個是所有想要訪問資源的線程必須知道用來保護資源的CRITICAL_SECTION結構的地址,第二個是任何線程試圖訪問被保護的資源之前,必須對CRITICAL_SECTION結構的內部成員進行初始化。

下面的函數用來進行初始化

void InitializerCriticalSection(PCRITICAL_SECTION pcs);

當線程不在需要訪問共享資源的時候,應該調用下面的函數來清理結構

void deleteCriticalSection(PCRITICAL_SECTION pcs);

EnterCriticalSection會檢查結構體中的成員變量,這些變量表示是否有線程正在訪問資源,以及哪個線程正在訪問資源。EnterCriticalSection會執行下面的測試:

1.如果沒有線程正在訪問資源,那么EnterCriticalSection會更新成員變量,以表示調用線程已經獲準對資源的訪問,并立即訪問,這樣線程就可以繼續執行

2.如果成員變量表示調用線程已經獲準訪問資源,那么EnterCriticalSection會更新變量,以表示調用線程被獲準訪問的次數,并立即放回,這樣線程就可以繼續執行。這樣的情況非常少見,只有當線程調用LeaveCriticalSection之前連續調用EnterCriticalSection兩次以上才會發生。

3.如果成員變量表示有一個(調用線程之外的其他)線程已經獲準訪問資源,那么EnterCriticalSection會使用一個事件內核對象來吧線程切換到等待狀態。一旦當前正在訪問資源的線程調用了LeaveCriticalSection,系統會自動更新結構的成員變量并將等待中的線程切換回可調度狀態。

我們也可以用下面的函數來代替EnterCriticalSection

Bool TryEnterCriticalSection(PCRITICAL_SECTION pcs);

TryEnterCriticalSection從來不會讓調用線程進入等待狀態,他會通過返回值來表示調用線程是否獲準訪問資源,因此如果TryEnterCriticalSection發現資源正在被其他線程訪問,那么它會返回false。每一個返回true的TryEnterCriticalSection調用必須有一個對應的LeaveCriticalSection。

當線程試圖進入一個關鍵段,但這關鍵段正在被另一個線程占用的時候,函數會立即把調用線程切換到等待狀態。這意味著線程必須從用戶模式切換到內核模式,這個切換的開銷非常大。為了提高性能,可以將旋轉鎖合并到關鍵段中,因此當調用EnterCriticalSection的時候,他會用一個旋轉鎖不斷的循環,嘗試在一段時間內獲取的對資源的訪問權,只有當嘗試失敗的時候買線程才會切換到內核狀態并進到等待狀態。

為了在是因關鍵段的時候同時使用旋轉鎖,必須調用以下的函數來初始化關鍵段

Bool InitializeCriticalSectionAndSpinCount(PCRITICAL_SECTION pcs,DWORD dwSpinCount);

與InitializerCriticalSection相似,但是第二個參數是我們希望旋轉鎖循環的次數,我們也可以通過下面的函數來改變關鍵段的旋轉次數

DWORD WINAPI SetCriticalSectionSpinCount(_Inout_?LPCRITICAL_SECTION lpCriticalSection,_In_????DWORD ?????????????dwSpinCount );

用來保護進程對的關鍵段所使用的旋轉次數大約是4000,這里作為參考。

SRWLock的目的和關鍵段系統,對一個資源進行保護,不讓其他資源訪問他。但是與關鍵段不同,SRWLock允許我們區分哪些想要讀取資源的值的線程(讀取者線程)和想要更新資源的值的線程(寫入者線程)。讓所有的讀取者線程在同一時刻訪問共享資源應該是可行的,只有當寫入者線程需要對資源進行更新的時候才需要同步,在這樣子情況下,寫入者線程應該獨占對資源的訪問權:任何其他線程。

首先我們需要分配一個SRWLOCK結構并用InitialSRWLock函數來對他進行初始化

VOID WINAPI InitializeSRWLock(?_Out_? PSRWLOCK SRWLock? );?

一旦SRWLock的初始化完成后,寫入者線程就可以調用AcquireSRWLockExclusive,將SRWLOCK對象的地址作為參數傳入,以嘗試獲得對被保護資源的獨占訪問權。

VOID WINAPI AcquireSRWLockExclusive(? _Inout_? PSRWLOCK SRWLock? );?

在完成對資源的更新之后。應該調用ReleaseSRWLockExclusive函數,并將SRWLOCK對象的地址作為參數傳入,解除對資源的鎖定。

VOID WINAPI ReleaseSRWLockExclusive(?? _Inout_? PSRWLOCK SRWLock? );?

讀取者的操作
讀取者調用的兩個參數是:
VOID AcquireSRWLockShared(PSRWLOCK SRWLock);??
VOID ReleaseSRWLockShared(PSRWLOCK SRWLock);??
不存在刪除或銷毀SRWLock的函數,系統會自動執行清理工作。
與關鍵段相比,SRWLock缺乏下面兩個特性:
(1)不存在TryEnter(Shared/Exclusive)SRWLock之類的函數。如果鎖已經被占用,那么調用AcquireSRWLock(SHared/Exclusive)會阻塞調用線程。
(2)不能遞歸調用SRWLOCK。一個線程不能為了多次寫入資源而多次鎖定資源,然后多次調用ReleaseSRWLock來釋放對資源的鎖定。
但是,如果可以接受這些限制,就可以用SRWLock來代替關鍵段,并獲得實際性能和可伸縮性的提升。

三、同步機制性能的比較

通過一個簡單的基準測試可以比較各種同步機制的性能:產生1、2和4個線程,使用不同的同步機制重復執行相同的任務,在雙處理器上運行,得出的結果是:

用戶模式下同步機制性能的對比實驗結果如下(計數單位:微秒)



線程數

Volatile Read

Volatile Write

Interlocked Increment

Critical Section

SRWLock Shared

SRWLock Exclusive

Mutex

1

8

8

35

66

66

67

1060

2

8

76

153

268

134

148

11082

4

9

145

361

768

244

307

23785

各種機制對比:

(1)讀取volatile長整型值,讀取非常快,因為不需要進行任何同步,與CPU的高速緩存完全無關。

(2)寫入volatile長整型值。單線程的時間和讀取差不多,但是雙線程的時候時間不只是加倍,這是因為CPU之間必須相互通信以維護高速緩存的一致性。如果機器有更多的CPU,那么性能還會下降,因為需要在更多的CPU之間進行通信來使得所有CPU的高速緩存一致。

(3)使用InterlockedIncrement來安全遞增一個volatile長整型值。

它比第一種方法要慢,這是因為CPU必須鎖定內存。使用兩個線程要比一個線程慢得多,這是因為必須在兩個CPU之間來回傳輸數據以維護高速緩存的一致性。

(4)使用關鍵段來讀取一個volatile長整型值。

關鍵段比較慢,是因為我們必須先進入再離開。進入和離開需要修改CRITICAL_SECTION結果中的多個字段。4個線程需要花費更多時間,是因為上下文切換增大了發生爭奪現象的可能性。

(5)使用SRWLock來讀取一個volatile長整型值。

當有多個線程的時候,讀操作比寫操作快。由于多個線程會不斷地寫入鎖的字段以及它保護的數據,因此各CPU必須在它們的高速緩存之間來回傳輸數據。

它的性能和關鍵段差不多,但是很多時候要優于關鍵段。建議的做法是用SRWLock替代關鍵段。

(6)使用同步內核對象互斥量。

互斥量是目前性能最差的,是因為等待互斥量以及后來釋放互斥量需要線程每次在用戶模式和內核模式之間卻換,開銷很大。

總結:應該首先嘗試不要共享數據,然后依次使用volatile讀取、volatile寫入、Interlocked函數、SRWLock以及關鍵段。僅當這些都不能滿足要求的時候,再使用內核對象。

Windows提供SleepConditionVariableCS或SleepConditionVariableSRW函數,等待條件變量。線程在等待該條件變量時,會以原子方式把鎖釋放并將自己阻塞,直到該條件變量被觸發時為止。

Bool?SleepConditionVariableCS(??PCONDITION_VARIABLE?pConditionVariable,??PCRITICAL_SECTION?pCriticalSection,??DWORD?dwMilliseconds);??Bool?SleepConditionVariableSRW(??PCONDITION_VARIABLE?pConditionVariable,??PSRWLOCK?pSRWLock,??DWORD?dwMilliseconds??ULONG?Flags);

?pConditonVariable指向一個以初始化的條件變量,調用線程將等待該條件變量。第二個參數指向一個關鍵段或是SRWLock對象。該關鍵段或SRWLock用來同步對共享資源的訪問。Flags指定一旦條件變量被觸發,線程將以何種方式獲得鎖。對讀取者線程來說應該傳入CONDITION_VARIABLE_LOCKMODE_SHARED表示希望共享對資源的訪問。對于寫入者線程應該傳入0,表示獨占資源。

dwMilliseconds表示我們希望線程花多少時間來等待條件被觸發。在指定的時間用完時,如果條件變量尚未被觸發,函數返回false,否則為true。

當另一個線程檢測到相應的條件已經滿足時,比如存在一個元素可以讓讀取者線程讀取。它會調用WakeConditionVariable或WakeAllConditionVariable,觸發條件變量。這樣調用Sleep*函數而阻塞在該條件變量的線程就會被喚醒。

Void?WakeConditonVariable(??PCONDITION_VARIABLE?ConditionVariable);?? Void?WakeAllConditionVariable(??PCONDITION_VARIABLE?ConditionVariable);WakeConditionVariable會使SleepConditionVariable*等待的同一個條件變量被觸發的線程得到鎖并返回。當此線程釋放這個鎖的時候,不會喚醒其他正在等待此條件變量的線程。




總結

以上是生活随笔為你收集整理的用户模式下的线程同步的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 麻豆精品视频免费观看 | 国产第一页在线播放 | 一区二区三区黄色 | 爱爱视频天天干 | 久久午夜精品 | 香蕉视频免费在线观看 | 色www情 | 三级国产网站 | 在线播放无码后入内射少妇 | 麻豆网站在线播放 | 国产熟女一区二区丰满 | 免费在线观看成人av | 中文字幕亚洲乱码熟女1区2区 | 欧美另类色 | 妺妺窝人体色777777 | 日韩毛片免费观看 | 欧美精品在线观看一区二区 | 国产精品高清在线 | 中文字幕在线免费看线人 | 欧美视频一区在线 | 精品丰满人妻无套内射 | 天天干天天爱天天操 | 能看毛片的网站 | 国产区视频在线观看 | 秋霞成人网 | 夜夜嗨av一区二区三区 | 奇米成人影视 | 亚洲逼逼 | 天天爱天天射 | 亚洲欧美中文字幕5发布 | 亚洲黄色网络 | 日本va欧美va国产激情 | 91玉足脚交嫩脚丫在线播放 | 欧美中文字幕在线播放 | 日韩黄色三级 | 亚洲一区二区av在线 | 丰满熟妇乱又伦 | 秋霞影院午夜老牛影院 | 高跟鞋av | 绯色av一区二区三区高清 | 欧美黄色录像视频 | 91一区二区在线观看 | 亚洲色图视频在线 | a在线v| avtt香蕉久久| 欧美四区 | 老外黄色一级片 | 男人与雌性宠物交啪啪 | 少妇人妻偷人精品无码视频 | 国产一二三 | 精品三级视频 | 国产一级片在线播放 | 亚洲精品无码一区二区 | 91九色视频 | 被警察猛c猛男男男 | 日日骑夜夜操 | 邻居少妇张开双腿让我爽一夜 | 男生舔女生胸 | 亚洲国产精品久久 | 亚洲欧美另类一区 | 五月婷婷久 | 成人一级影视 | 痴汉电车在线播放 | 一区二区在线播放视频 | 色人阁五月 | 亚洲高清毛片一区二区 | 琪琪免费视频 | 阿的白色内裤hd中文 | 超碰青草 | 久操不卡 | 亚洲成年人在线 | 天天激情 | 波多野结衣精品视频 | 91精品国产综合久久久蜜臀 | 国产精品久久久久久久久久久久久久久久久久 | 国产偷人妻精品一区二区在线 | 欧美激情校园春色 | 亚洲欧美久久久 | 年代下乡啪啪h文 | 成人午夜高清 | 国产tv在线观看 | 午夜激情视频网站 | 久久国产中文 | 欧美专区第一页 | 色午夜婷婷 | 丰满人妻在公车被猛烈进入电影 | 污视频免费在线观看网站 | 欧美一区二区三区久久精品 | 67194成人 | 天码人妻一区二区三区在线看 | 欧美sm凌虐视频网站 | 欧美私人网站 | 欧美一区二区三区免费视频 | 男女视频在线免费观看 | 91av国产在线| 特级淫片裸体免费看冫 | 俺也来俺也去俺也射 | 人人爽人人射 | www免费视频|