Multithreading 我可以获取包含CriticalSection的线程的id吗?

Multithreading 我可以获取包含CriticalSection的线程的id吗?,multithreading,winapi,critical-section,Multithreading,Winapi,Critical Section,我想围绕一段复杂的多线程代码编写一些断言。 有什么方法可以做一个 assert(GetCurrentThreadId() == ThreadOfCriticalSection(sec)); 据我所知,没有文件记录的方法来获取这些信息。如果您查看这些头,CRITICAL_SECTION结构包含一个线程句柄,但我不会依赖这些信息,因为内部结构可能会在没有通知的情况下更改。更好的方法是,每当线程进入/退出临界区时,自己维护这些信息。您的要求没有意义。如果当前线程不是关键部分中的线程,那么当前线程中的

我想围绕一段复杂的多线程代码编写一些断言。 有什么方法可以做一个

assert(GetCurrentThreadId() == ThreadOfCriticalSection(sec));

据我所知,没有文件记录的方法来获取这些信息。如果您查看这些头,CRITICAL_SECTION结构包含一个线程句柄,但我不会依赖这些信息,因为内部结构可能会在没有通知的情况下更改。更好的方法是,每当线程进入/退出临界区时,自己维护这些信息。

您的要求没有意义。如果当前线程不是关键部分中的线程,那么当前线程中的代码将不会运行,在尝试锁定关键部分时将被阻止

如果您的线程实际上在临界区内,那么您的断言将始终为真。如果不是,你的断言将永远是错误的


所以我的意思是,假设您能够跟踪关键部分中的线程,如果您将断言放在关键部分代码中,那么它总是正确的。如果您将它放在外部,它将始终为false。

如果您想正确地执行此操作,我认为您已经在关键部分周围使用了一个包装器对象,它将跟踪调试版本中哪个线程(如果有)拥有每个CS

i、 e.与直接调用EnterCriticalSection不同,您需要在包装器上调用一个方法,该方法执行EnterCriticalSection,然后在成功时,将GetCurrentThreadId存储在DWORD中,断言将对其进行检查。另一种方法是在调用LeaveCriticalSection之前将线程ID DWORD置零

在发布版本中,包装器可能会省略额外的内容,只调用Enter/LeaveCriticalSection

正如卡萨布兰卡指出的,所有者线程ID在当前的CRITICAL_节结构中,因此使用我建议的包装器将存储冗余信息。但是,正如卡萨布兰卡也指出的那样,关键截面结构不是任何API合同的一部分,可能会发生变化。事实上,它在过去的Windows版本中已经发生了变化

了解内部结构有助于调试,但不应在生产代码中使用

因此,您使用哪种方法取决于您希望解决方案的正确程度。如果您只是想在当前版本的Windows上找到一些临时的问题,那么直接使用CRITICAL_SECTION字段对我来说是合理的。只是不要期望这些断言永远有效。如果你想要更持久的东西,使用包装器


使用包装器的另一个优点是,您将获得RAII。i、 e.包装器的构造函数和析构函数将处理InitializeCriticalSection和DeleteCriticalSection调用,因此您不再需要担心它们。说到这里,我发现有一个helper对象非常有用,它在构造时进入CS,然后在销毁时自动离开。没有一个临界区段意外地被锁定,因为一个函数有一个早期的返回隐藏在它的中间……/P>这是有意义的。我有一个API,带有锁、解锁和许多辅助函数。我想在所有worker函数中放置一个断言,并检查调用方在调用一组其他函数之前是否忘记调用lock。我想您从未了解过契约式设计的编程风格。我不明白这是工人的责任。这是打电话的人的工作。您正在让员工了解经理/协调器的实施细节。那里的某个地方违反了SRP。我个人认为你应该重新审视你的要求,并考虑如果你的客户有可能犯这个错误,那么也许你应该重新修改你的API以防止它发生。是的,我听说过契约式设计的编程风格,但我不一定喜欢它,我也不认为你的要求暗示了它。你的观点也适用于所有其他基于状态的API,你只能在某些状态下调用某些函数。这没有道理,也不实际。在埃菲尔铁塔中,程序员花费大量的时间来建立状态机需求/规范的先决条件模型。你所说的是不关心不要测试,在调用方中重复验证测试,而不是被调用的或者根本不检查,相信全能者的善良。我不相信全能者:+1——这是解决C++中的问题的正确方法。由于CritSec结构的状态可能会在您的脚下发生变化,因此,您不能直接在CritSec结构中的线程句柄上进行任何检查。使用保持锁定标志的RAII lock_guard类。