多年來,Windows中關鍵部分的實現已經發生了變化,但它一直是用戶模式和內核調用的結合。
CRITICAL_SECTION是一個包含用戶模式更新值,內核模式對象的句柄-EVENT或類似的東西以及調試信息的結構。
EnterCriticalSection使用互鎖的測試和設置操作來獲取鎖。如果成功,這就是所需要的(幾乎它也會更新所有者線程)。如果set-and-set操作失敗,則使用更長的路徑,這通常需要等待WaitForSignleObject
的內核對象。如果用InitializeCriticalSectionAndSpinCount
進行初始化,則EnterCriticalSection
可能會旋轉重試以在用戶模式下使用互鎖操作進行採集。
下面是EnterCriticialSection
「快」 /無競爭的路徑在Windows 7(64位)與一些意見直列
0:000> u rtlentercriticalsection rtlentercriticalsection+35
ntdll!RtlEnterCriticalSection:
00000000`77ae2fc0 fff3 push rbx
00000000`77ae2fc2 4883ec20 sub rsp,20h
; RCX points to the critical section rcx+8 is the LockCount
00000000`77ae2fc6 f00fba710800 lock btr dword ptr [rcx+8],0
00000000`77ae2fcc 488bd9 mov rbx,rcx
00000000`77ae2fcf 0f83e9b1ffff jae ntdll!RtlEnterCriticalSection+0x31 (00000000`77ade1be)
; got the critical section - update the owner thread and recursion count
00000000`77ae2fd5 65488b042530000000 mov rax,qword ptr gs:[30h]
00000000`77ae2fde 488b4848 mov rcx,qword ptr [rax+48h]
00000000`77ae2fe2 c7430c01000000 mov dword ptr [rbx+0Ch],1
00000000`77ae2fe9 33c0 xor eax,eax
00000000`77ae2feb 48894b10 mov qword ptr [rbx+10h],rcx
00000000`77ae2fef 4883c420 add rsp,20h
00000000`77ae2ff3 5b pop rbx
00000000`77ae2ff4 c3 ret
因此,底線是,如果線程並不需要一個diassembly阻止它不會使用系統調用,只是互鎖的測試和設置操作。如果需要阻止,則會有系統調用。釋放路徑也使用互鎖測試和設置,並且如果其他線程被阻塞,可能需要系統調用。
比較這對互斥總是需要一個系統調用NtWaitForSingleObject
和NtReleaseMutant
互斥使用'CreateMutex'。 – Mehrdad 2011-03-03 03:01:06
自旋鎖實際上是用於內核使用的(當然,您可以在自己的程序中不做任何事情,但這沒有幫助)。以下關於自旋鎖的答案以前是誤導性的,但現在海報已經糾正了它。 – casablanca 2011-03-03 03:28:51
抱歉有關混淆。 – 0xC0000022L 2011-03-03 03:35:19