关闭 MFC 对话框时的多线程对象破坏

Posted

技术标签:

【中文标题】关闭 MFC 对话框时的多线程对象破坏【英文标题】:Multithreaded object destruction on closing MFC dialog 【发布时间】:2012-08-02 23:27:12 【问题描述】:

所以,这就是问题所在:

我已经为 libtorrent c++ 库编写了一个封装类,展示了简化的 API。它(包装器)有一个堆栈分配的成员,它是 libtorrent 的主要会话对象。 该库本身使用 boost 框架,以及它的线程特性——它是多线程的。 (我必须说我对 boost 不是很熟悉。)

现在,我想创建一个简单的基于 MFC 对话框的应用程序,该应用程序将有几个按钮用于管理会话、进度条等。

libtorrent 会话的析构函数可能需要一段时间才能完成(因为它需要通知跟踪器它正在关闭)。退出时会提示用户使用 MessageBox 确认下载终止,因此我认为将包装器对象作为应用程序类的成员而不是 CDialog (包装器析构函数,因此会话将启动)是个好主意在对话框关闭后)。 Libtorrent 文档还指出,在调用析构函数之前关闭诸如窗口之类的 UI 是个好主意。

有趣的部分来了——一切正常,直到我关闭对话框。该过程继续存在几秒钟,然后因一些与提升相关的锁/关键部分的东西而崩溃(这是调试器指向的地方,在提升的标头之一中进行了一些锁定/释放调用)......

编辑 似乎在关闭时,从主窗口执行了一些线程检查,并且它进入了一些“不规则”状态,在这种状态下它做了一些导致提升失败的事情。我在想gui线程需要某种“加入”,以等待其他线程终止......

如果有人理解我在这里试图解释的内容,并且知道我做错了什么,或者对此概念有替代解决方案,我将不胜感激。 谢谢。

【问题讨论】:

【参考方案1】:

您可以在退出之前等待 Boost 线程加入。我有一个使用 Boost 线程的 Output_Processor 类。我通过队列与它交互。一旦我想关闭应用程序,我就会在其队列中放置一个关闭命令。 Output_Processor 线程在处理完该命令后返回。然后我的加入块返回,应用程序的其余部分可以正常关闭。

...
_output_processor_queue->write(shutdown_command);

// Wait for output processor thread to join.
_output_processor_thread->join();

_output_processor_initialized = false;
...

【讨论】:

正如我所说,我在 torrent 库周围编写了包装器。您的回答与问题部分无关,表明我应该弄乱图书馆的来源,我很确定我不会这样做。 Libtorrent 绝对应该自己处理加入线程。【参考方案2】:

好的,问题解决了。 我所做的只是我最初创建了一个动态包装器对象,并在 doModal() 返回后将其删除。此时主线程阻塞,等待删除操作结束,这基本上是直到 libtorrent 会话被破坏。但是,非动态对象的特殊行为仍然存在。

【讨论】:

以上是关于关闭 MFC 对话框时的多线程对象破坏的主要内容,如果未能解决你的问题,请参考以下文章

怎么在基于对话框的MFC程序中实现多线程?

MFC多线程创建教程示例

如何在多线程函数MFC中获取对话框类的指针

java中的多线程

我的 MFC C++ .dll 的多线程

MFC中多线程中静态函数调用成员函数的问题