我在一個預先調用C++庫的.NET(C#,3.5)應用程序中遇到了一個奇怪的Boost(v1.38)互斥體死鎖。在獲得讀取鎖定之後,某個點會[正確]拋出異常,並且該異常一直回到受管理的.NET代碼(處理該代碼的位置)。在C++庫中的下一個呼叫嘗試使用setter方法上唯一的鎖AQUISITION掛起無限期地(大概是讀鎖未釋放):在拋出異常後未釋放Boost共享互斥體
ntdll.dll!NtWaitForSingleObject() + 0x15 bytes
kernel32.dll!WaitForSingleObjectEx() + 0x43 bytes
kernel32.dll!WaitForSingleObject() + 0x12 bytes
OurCPPLib.dll!boost::shared_mutex::unlock_upgrade_and_lock() Line 478 + 0x11 bytes C++
OurCPPLib.dll!boost::unique_lock<boost::shared_mutex>::unique_lock<boost::shared_mutex>(boost::detail::thread_move_t<boost::upgrade_lock<boost::shared_mutex> > other) Line 788 C++
OurCPPLib.dll!boost::upgrade_to_unique_lock<boost::shared_mutex>::upgrade_to_unique_lock<boost::shared_mutex>(boost::upgrade_lock<boost::shared_mutex> & m_) Line 802 + 0x98 bytes C++
OurCPPLib.dll!OurClass::SetSomething(double something) Line 95 C++
類定義了一些get和set方法(讀者/作家),並實現它們像這樣:
boost::shared_mutex _calcSharedMutex;
RETURNCODE GetSomething(double& something)
{
boost::shared_lock<boost::shared_mutex> lock(_calcSharedMutex);
return _anotherObject->GetSomething(something);
}
RETURNCODE SetSomething(double something)
{
boost::upgrade_lock<boost::shared_mutex> lock(_calcSharedMutex);
boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
return _anotherObject->SetSomething(something);
}
到_anotherObject-> GetSomething()的調用將在罕見的情況拋出一個異常:
throw std::invalid_argument("Unknown something");
此外, re是getter中的一些對C++庫本身的try/catch中的_anotherObject-> GetSomething()進行的調用,防止異常返回到託管代碼,並且不會導致此死鎖。未處理的異常是否破壞了互斥鎖範圍的解鎖?
在此先感謝任何可能有所洞察的人!
這段代碼是用/ clr生效的嗎?如果是這樣,你是否在它之前放置了#pragma managed(push,off)? –
未使用/ clr開關編譯C++。 – roken
這很奇怪,這應該工作。除了實際顯示問題的演示程序之外,您唯一的選擇是使用/ EHa編譯該C++代碼。儘管* that *沒有任何意義。 –