我有一个维护列表的对象;其中一个辅助方法需要
- 锁定列表
- 找到第一个元素
- 解锁列表
- 通知另一个线程开始清理操作
- 等待另一个线程完成
- 重复此操作直到列表为空。
清理操作从另一个线程的列表中删除对象,因此它需要在两者之间锁定列表。
只要不调用 helper 时已经持有列表上的锁,这就可以正常工作,因为解锁操作实际上不会允许其他线程访问列表,所以我想在此标记一个错误案例。
据我所知,CRITICAL_SECTION
API 没有提供官方支持的方式来查询当前进程是否持有这个对象,所以我正在考虑“hack-ish”方法(毕竟,它是一种调试辅助工具,并不打算用于生产代码中):
变体1是检查CRITICAL_SECTION
结构的OwningThread
字段,但不知有没有保证这个字段是
- 始终包含来自与
GetCurrentThreadId()
结果相同的数字空间的线程 ID - 总是在任何线程获取锁时更新
- 总是在我自己的线程释放锁时清除
变体 2 是锁定 CRITICAL_SECTION
,然后检查 RecursionCount
;这假定递归计数器具有固定的起始值。
是否有任何我遗漏的东西可以用来构建一个有点面向 future 的断言语句(也就是说,它会在我解释所有内容的注释附近的一行代码中大声中断)断言语句当前线程不是某个CRITICAL_SECTION
的持有者?
最佳答案
制作你自己的关键部分来提供这样的功能。在调试版本中使用它。在发布版本中,使用常规临界区。
一种简单的方法是使用两个关键部分和一个所有者字段。获取这样的作品:
获取第一个临界区。
获取第二个临界区。
设置此线程的所有者。
释放第二个临界区。
发布是这样的:
获取第二个临界区。
将所有者设置为无。
释放第一个临界区。
释放第二个临界区。
断言是这样工作的:
获取第二个临界区。
断言所有者不是该线程。
释放第二个临界区。
更新:上面有一个错误。它错误地处理了这种情况:锁定,锁定,解锁,断言我们不持有关键部分但我们持有。解决方法可能是保持“锁定计数”。您不必使用锁定计数将 CS 设置为“无主”。如果锁定计数为零,则它是无主的。所以断言路径“unowned or owner not this thread”。
关于windows - 断言当前线程不持有 CRITICAL_SECTION 锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9290703/