1

所以 App Verifier 抛出了这个异常。据我所知,这条消息的文字有点误导。问题似乎是临界区是由在临界区被销毁之前被销毁的线程创建的。

这是一个相对简单的修复,但有谁知道除了创建线程之外的线程破坏关键部分的后果是什么?有多危险?只是担心临界区句柄会“泄漏”还是有更隐蔽的副作用?

其他一些信息:

  • 用 C++ 编写的应用程序(当然是在 Windows 上)
  • 使用 InitializeCriticalSelection 创建的临界区
  • 最终使用 DeleteCriticalSection 删除临界区
4

3 回答 3

2

我相信您对消息的解释是正确的。我能找到的唯一参考如下。正如作者建议的那样,堆栈跟踪是一个很好的线索

我挖了一会儿,找不到任何具体原因为什么您不能在不同线程上创建和删除关键部分。但是我确实想知道您为什么要这样做?可以这么说,让一个线程拥有一个关键部分似乎是最佳实践。在线程之间切换临界区引入了另一种通信方式和潜在的错误(可以做到,只是更有趣)。

于 2009-05-28T13:55:02.130 回答
2

Seems accepted answer talks about creation of critical section, which is not what this message is about. Eran's answer covered the real cause of the message, but here it is in TL;DR terms:

Application verifier detected a thread, that acquired a critical section lock, is attempting to exit while the section is still locked

It is not complaining that thread created critical section and is now terminating. This has nothing to do with who creates and destroys the section. It is complaining, and very legitimately, that the thread owns the lock on that critical section and terminating. They could've made the wording of that message so much clearer.

于 2012-01-15T08:09:20.557 回答
1

与诸如 COM 对象之类的野兽相反,临界区生命周期并不绑定到某个线程。关键部分的构建分为两个阶段:在创建时,它们仅由几个结构组成。在两个或多个线程争用时,会创建一个内核互斥锁以正确处理同步。任何线程都可以创建、访问和破坏结构和互斥锁,无论它是否创建了临界区。

要回答您的问题,以上意味着您在一个线程中创建 CS 并在另一个线程中销毁它应该没有问题。然而,这可能意味着设计存在一些问题。如果您还没有这样做,请考虑用一个类包装 CS,该类将在其构造函数中初始化 CS,并在其析构函数中销毁它(MFC 的 CCriticalSection 会这样做)。然后,在比使用它的范围更高的范围内创建包装器(全局、静态类成员等)。应该使创建和清理更容易。

最后,关于错误消息本身 - 被删除的线程是否有可能进入 CS 而没有机会离开它(由于异常等)?如果是这种情况,您会收到一条看起来很奇怪的消息,指出一个真正的问题。

于 2009-06-05T21:23:26.060 回答