我有一个维护列表的对象;
需要帮助方法之一清理操作从另一个线程中删除列表中的对象,因此需要锁定列表。
这个工作正常,只要没有调用已经保持的列表上的锁,因此解锁操作实际上不允许其他线程访问列表,所以我想在此标记错误情况下。
据我所知,CRITICAL_SECTION
API没有提供官方支持的方式来查询当前进程是否包含此对象,所以我正在考虑“hack-ish”方法(毕竟,它是一个调试辅助工具,不打算进入生产代码):
变体1是检查OwningThread
结构的CRITICAL_SECTION
字段,但我想知道是否保证此字段是
GetCurrentThreadId()
结果变体2是锁定CRITICAL_SECTION
,然后检查RecursionCount
;这假设递归计数器具有固定的起始值。
我是否有任何我可以用来建立一个有点面向未来的东西(也就是说,它会在我所解释的所有评论附近的代码行中大声破解)断言声明当前线程不某个CRITICAL_SECTION
的持有者?
答案 0 :(得分:2)
制作您自己的关键部分,提供此类功能。在调试版本中使用它。在发布版本中,使用常规临界区。
一种简单的方法是使用两个关键部分和一个所有者字段。获得的工作方式如下:
获取第一个关键部分。
获取第二个关键部分。
将所有者设置为此主题。
发布第二个关键部分。
发布的工作原理如下:
获取第二个关键部分。
将所有者设为无。
发布第一个关键部分。
发布第二个关键部分。
Assert的工作原理如下:
获取第二个关键部分。
断言所有者不是这个主题。
发布第二个关键部分。
更新:上面有一个错误。它错误地处理了这种情况:锁定,锁定,解锁,断言我们没有关键部分,但我们这样做。修复可能是为了保持“锁定计数”。您不必使用锁定计数将CS设置为“无主”。如果锁定计数为零,则它是无主的。所以断言路径“无主或所有者不是这个线程”。
答案 1 :(得分:1)
我使用类似的东西
class CriticalSection
{
private:
CRITICAL_SECTION section_;
unsigned int owning_thread_id_;
unsigned int lock_count_;
public:
CriticalSection()
{
InitializeCriticalSection(§ion_);
owning_thread_id_ = 0;
lock_count_ = 0;
}
~CriticalSection()
{
DeleteCriticalSection(§ion_);
}
void enter()
{
EnterCriticalSection(§ion_);
owning_thread_id_ = GetCurrentThreadId();
lock_count_ ++;
}
void leave()
{
if( GetCurrentThreadId() == owning_thread_id_ )
{
lock_count_ --;
if( lock_count_ == 0 )
owning_thread_id_ = 0;
}
LeaveCriticalSection(§ion_);
}
bool tryEnter()
{
if( TryEnterCriticalSection(§ion_))
{
owning_thread_id_ = GetCurrentThreadId();
lock_count_ ++;
return true;
}
return false;
}
bool isCurrentThreadEntered()
{
return GetCurrentThreadId() == owning_thread_id_;
}
int getLockCount() { return lock_count_; }
unsigned int getOwningThreadID() { return owning_thread_id_; }
};