std::timed_mutex::try_lock_for 立即失败
std::timed_mutex::try_lock_for fails immediately
我是第一次使用std::timed_mutex
,它的行为方式不符合我的预期。它似乎立即失败,而不是等待互斥锁。我以毫秒为单位提供锁定超时(如图 http://www.cplusplus.com/reference/mutex/timed_mutex/try_lock_for/所示(。但是,对try_lock_for()
的调用立即失败了。
下面是处理锁定和解锁互斥锁的类:
const unsigned int DEFAULT_MUTEX_WAIT_TIME_MS = 5 * 60 * 1000;
class ScopedTimedMutexLock
{
public:
ScopedTimedMutexLock(std::timed_mutex* sourceMutex, unsigned int numWaitMilliseconds=DEFAULT_MUTEX_WAIT_TIME_MS)
m_mutex(sourceMutex)
{
if( !m_mutex->try_lock_for( std::chrono::milliseconds(numWaitMilliseconds) ) )
{
std::string message = "Timeout attempting to acquire mutex lock for ";
message += Conversion::toString(numWaitMilliseconds);
message += "ms";
throw MutexException(message);
}
}
~ScopedTimedMutexLock()
{
m_mutex->unlock();
}
private:
std::timed_mutex* m_mutex;
};
这就是它的使用方式:
void CommandService::Process( RequestType& request )
{
unsigned long callTime =
std::chrono::duration_cast< std::chrono::milliseconds >(
std::chrono::system_clock::now().time_since_epoch()
).count();
try
{
ScopedTimedMutexLock lock( m_classMutex, request.getLockWaitTimeMs(DEFAULT_MUTEX_WAIT_TIME_MS) );
// ... command processing code goes here
}
catch( MutexException& mutexException )
{
unsigned long catchTime =
std::chrono::duration_cast< std::chrono::milliseconds >(
std::chrono::system_clock::now().time_since_epoch()
).count();
cout << "The following error occured while attempting to process command"
<< "n call time: " << callTime
<< "n catch time: " << catchTime;
cout << mutexException.description();
}
}
下面是控制台输出:
The following error occured while attempting to process command
call time: 1131268914
catch time: 1131268914
Timeout attempting to acquire mutex lock for 300000ms
知道这是哪里出了问题吗?转换为std::chrono::milliseconds
是否正确?如何让try_lock_for()
等待锁?
附加信息:对try_lock_for()
的调用并不总是立即失败。很多时候,呼叫获得了锁,一切都按预期工作。我看到的失败是间歇性的。请参阅下面的回答,了解有关失败原因的详细信息。
问题的根本原因在 http://en.cppreference.com/w/cpp/thread/timed_mutex/try_lock_for 的try_lock_for()
描述中提到。在描述的末尾,它说:
与 try_lock(( 一样,此函数允许虚假失败,并且 返回 false,即使互斥锁未被任何其他线程锁定 timeout_duration中的某个时间点。
我天真地认为只有两种可能的结果:(1( 函数在时间段内获取锁,或 (2( 函数在等待时间过后失败。但还有另一种可能性,(3(函数在相对较短的时间内失败,原因不明。博士,我的坏。
我通过重写 ScopedTimedMutexLock
构造函数来循环try_lock()
直到获取锁或超过等待时间限制来解决此问题。
ScopedTimedMutexLock(std::timed_mutex* sourceMutex, unsigned int numWaitMilliseconds=DEFAULT_MUTEX_WAIT_TIME_MS)
m_mutex(sourceMutex)
{
const unsigned SLEEP_TIME_MS = 5;
bool isLocked = false;
unsigned long startMS = now();
while( now() - startMS < numWaitMilliseconds && !isLocked )
{
isLocked = m_sourceMutex->try_lock();
if( !isLocked )
{
std::this_thread::sleep_for(
std::chrono::milliseconds(SLEEP_TIME_MS));
}
}
if( !isLocked )
{
std::string message = "Timeout attempting to acquire mutex lock for ";
message += Conversion::toString(numWaitMilliseconds);
message += "ms";
throw MutexException(message);
}
}
其中now()
定义如下:
private:
unsigned long now() {
return std::chrono::duration_cast< std::chrono::milliseconds >(
std::chrono::system_clock::now().time_since_epoch() ).count();
}
对于那些迟到的人来说,这只是一个小小的提升。非常感谢您的帮助!
具有完全相同的行为(仅在 std::shared_timed_mutex 中(。经过一番挖掘发现,如果同一线程已经对互斥锁具有独占锁,则try_lock_for()
和try_lock_until()
都会立即失败,基本上节省了测试损坏代码的时间。
使用 gcc-9、gcc-10、clang-10 和 clang-12 进行测试。
没有测试其他可能的组合,例如请求共享锁上的独占锁或任何独占/共享锁上的共享锁。
- 如果没有malloc,链表实现将失败
- "error: no matching function for call to"构造函数错误
- 表示"accepting anything for this template argument" C++概念的通配符
- 使用 cmake 的 LLVM 构建在 tsan_libdispatch_mac.cc 期间失败; "Error: conflicting types for ..."
- 与卡特琳娜一起卷曲C++失败并得到"Undefined symbols for architecture x86_64"
- std::access for variant 在 clang 5 下编译失败
- 断言 for rapidJson 失败了
- IHTMLDocument2::get_body 在 CHtmlView for IE 11 中失败
- C++ for-each 语句触发"vector iterators incompatible"断言失败:this->_Getcont() == 0
- 在for循环内部使用setw是失败的
- std::vector push_back 在并行 for 循环中使用时失败
- 迭代器结束检查在“for”循环内递增后失败
- RC 文件更改以静默方式失败; "Cannot open the resource file for edit"
- 简单的for循环完成并失败运行
- zGuide for zeroMQ编译失败
- 使用基于范围的for()编译Slice模板失败
- XCode 构建失败"undefined Symbols for architecture x86_64"
- 错误:static_assert unordered_multimap的"This hash only works for enumeration types"失败
- 示例 XSD 失败并显示"error: no declaration found for element X"
- 为什么打印对象失败并显示"no match for 'operator<<'"错误?