代码之家  ›  专栏  ›  技术社区  ›  Lothar

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

  •  2
  • Lothar  · 技术社区  · 15 年前

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

    assert(GetCurrentThreadId() == ThreadOfCriticalSection(sec));
    
    3 回复  |  直到 15 年前
        1
  •  4
  •   Leo Davidson    15 年前

    如果你想正确地做到这一点,我认为你必须在关键部分周围使用一个包装器对象,它将跟踪哪个线程(如果有的话)拥有调试构建中的每个CS。

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

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

    正如卡萨布兰卡指出的,所有者线程ID位于当前的CRITICAL_SECTION结构中,因此使用我建议的包装器将存储冗余信息。但是,正如卡萨布兰卡也指出的那样,关键的_段结构不是任何API合同的一部分,可能会发生变化。(事实上 已在以前的Windows版本中更改。)

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

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

    (使用包装器的另一个优点是,你会得到RAII。也就是说,包装器的构造函数和析构函数将处理InitializeCriticalSection和DeleteCriticalSection调用,这样你就不必再担心它们了。说到这一点,我发现让一个助手对象在构造时进入CS,然后在销毁时自动离开它是非常有用的AL部分意外锁定,因为一个函数有一个早期的隐藏隐藏在它的中间…

        2
  •  1
  •   casablanca    15 年前

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

        3
  •  -1
  •   OJ.    15 年前

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

    如果你的线程实际上在临界区内,那么你的断言总是正确的。如果不是,你的断言将永远是错误的!

    所以我的意思是,假设你能够跟踪哪个线程在关键部分,如果你把你的断言放在关键部分代码中,它总是正确的。如果你把它放在外面,它总是假的。