std::mutex (互斥量內部實現SRWLOCK)

注意:mutex windows vista 以上系統用SRWLOCK 實現,winxp用的是參考 rtlocks.cpp 
critical_section  調用InterlockedCompareExchangePointer 來實現的 



Windows 7下  + vs2015 微軟最新c++11  std::mutex 內部實現剖析

一、	先說說微軟c++11 裏面實現的代碼,廢話不多說,上例子驗證猜想
Vs2015新建一個控制檯程序,代碼如下:
// mutex_d.cpp : 定義應用程序的入口點。
//此段代碼是死鎖程序,方便跳轉到內部實現!!!!
#include "stdafx.h"
#include "mutex_d.h"
#include<thread>
#include<mutex>
#include<iostream>

std::mutex test;


void t_fun()
{
	test.lock();//重入導致死鎖
	std::cout << "hello\n";
	test.unlock();
}

int main(int argc, TCHAR* argv[])
{
	test.lock();
	std::thread th(t_fun);
	th.join();

	return 0;
}

/*
讀寫鎖 SRWLOCK 使用方法

SRWLOCK srw;

InitializeSRWLock(&srw);
//一旦初始化完成,就可以對寫入線程調用AcquireSRWLockExclusive()函數和ReleaseSRWLockExclusive()函數
AcquireSRWLockExclusive(&srw);
//...寫入數據,寫入東西的時候該線程獨佔,其他任何線程不可進入
ReleaseSRWLockExclusive(&srw);

//對於只讀線程可以調用AcquireSRWLockShared()函數和ReleaseSRWLockShared()函數, 如下
AcquireSRWLockShared(&srw);
//..讀取數據,如果這時沒有寫入數據則多個讀取線程可以進行
ReleaseSRWLockShared)&srw);

*/
運行程序會導致卡主不動,此時貼上堆棧:
 
	ntdll.dll!_ZwWaitForKeyedEvent@16 ()	 
 	ntdll.dll!_RtlAcquireSRWLockExclusive@4 ()	 
 	msvcp140d.dll!__crtAcquireSRWLockExclusive(_RTL_SRWLOCK * pLock=0x00ff0388) 行 605	 
 	 	 	 	 	 	msvcp140d.dll!Concurrency::details::stl_critical_section_win7::lock() 行 166	 
 	 msvcp140d.dll!mtx_do_lock(_Mtx_internal_imp_t * mtx=0x00ff0380, const xtime * target=0x00000000) 行 100	 
 	 msvcp140d.dll!_Mtx_lock(_Mtx_internal_imp_t * mtx=0x00ff0380) 行 186	 
 	 mutex_d.exe!std::_Mtx_lockX(_Mtx_internal_imp_t * _Mtx=0x00ff0380) 行 70	 
 	 mutex_d.exe!std::_Mutex_base::lock() 行 43	 
 	 mutex_d.exe!t_fun() 行 16	 
 	 mutex_d.exe!std::_Invoker_functor::_Call<void (__cdecl*)(void)>(void(*)() && _Obj=0x00fe1235) 行 1375	 
 	 mutex_d.exe!std::invoke<void (__cdecl*)(void)>(void(*)() && _Obj=0x00fe1235) 行 1443	 
 	 mutex_d.exe!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Execute<0>(std::tuple<void (__cdecl*)(void)> & _Tup={...}, std::integer_sequence<unsigned int,0> __formal={...}) 行 240	 
 	 mutex_d.exe!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Run(std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > > * _Ln=0x0019f5d0) 行 247	 
 	 mutex_d.exe!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Go() 行 232	 
 	 mutex_d.exe!std::_Pad::_Call_func(void * _Data=0x0019f5d0) 行 209	 
 	ucrtbased.dll!invoke_thread_procedure(unsigned int(__stdcall*)(void *) procedure=0x00fe11c2, void * const context=0x0019f5d0) 行 92	 
 	 ucrtbased.dll!thread_start<unsigned int (__stdcall*)(void *)>(void * const parameter=0x005fdd50) 行 115	 
 	 kernel32.dll!@BaseThreadInitThunk@12 ()	 
 	 ntdll.dll!___RtlUserThreadStart@8 ()	 
 	 ntdll.dll!__RtlUserThreadStart@8 ()	


注意:如下三個函數其實是一樣的!!!!!
{
    Kernel32.dll !AcquireSRWLockExclusive( PSRWLOCK SRWLock
	ntdll.dll!_RtlAcquireSRWLockExclusive@4 ()	 
 	msvcp140d.dll!__crtAcquireSRWLockExclusive(_RTL_SRWLOCK * SRWLock)
}
結論 windows下  std:: mutex內部使用了讀寫鎖SRWLOCK 和 臨界區相似的功能!!
源碼位置:
Microsoft Visual Studio 14.0\VC\crt\src\stl\primitives.h
virtual void lock() override
        {
            __crtAcquireSRWLockExclusive(&m_srw_lock);
        }

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章