与主线程相比,在辅助线程上崩溃是不是有优势?

Posted

技术标签:

【中文标题】与主线程相比,在辅助线程上崩溃是不是有优势?【英文标题】:Are there advantages to a crashing on a secondary thread versus the main one?与主线程相比,在辅助线程上崩溃是否有优势? 【发布时间】:2011-04-01 10:12:00 【问题描述】:

我在一个大型代码库中发现了这段代码

DWORD WINAPI ThreadFunc (LPVOID lpParam)
 
    int *x = 0;
    *x = 1234; // Access violation

    return 0; 


void Manager::Crash ()

    Log("Received a remote command to crash Server.");

    DWORD dwThreadId, dwThrdParam = 1; 
    HANDLE hThread = ::CreateThread(NULL, 0, ThreadFunc, &dwThrdParam, 0, &dwThreadId);
 

我的问题是:为什么要使用线程?如果ThreadFunc 中的代码直接在Manager::Crash 中完成,会或多或少是线程安全的吗?如果我消除崩溃,我不愿意进行更改。

【问题讨论】:

你从哪里得到这个代码? 有趣的思想实验,但这不是一个好标题。 “与主线程相比,在辅助线程上崩溃是否有优势?” @quixoto:好标题,已修复。 @Maz:为什么? 嗯...为什么不直接调用 exit() 或 terminate() 呢?这是关闭服务器的极其复杂的代码...... 【参考方案1】:

他不想处理发生的异常。收到Manager::Crash 的原始线程继续。 AV 异常不一定会终止进程。尽管在这种情况下,__try/__except 块未处理的事实(注意,是 SEH try block,而不是 C++ 块),但未处理的 second chance 异常终止进程。但也许他想强制Dr. Watson/WER 加入,或者post-mortem debugger 启动,或者闯入当前的调试器。谁知道...

其实,天啊!如果主线程确实安装了 SEH 处理程序,它不会使进程崩溃。 QED。

【讨论】:

我会说“他不希望处理任何抛出的异常。原始线程可能有一个 SEH 块,并且会捕获它。” @GMan:是的,我很确定就是这样,避免在主线程中安装任何 SEH。在我编辑了我的“d'oh”时刻后立即看到了你的评论:) 这完全值得在代码中添加注释。【参考方案2】:

您首先需要询问是哪个程序员编写的,但在这样的线程中崩溃的原因可能是绕过一个旨在捕获主线程中的段错误的异常处理程序。这可能是打破源代码管理的延时视图并向肇事者发送电子邮件的好时机。

顺便说一句,这也是引发 CPU 异常的一种不必要的笨拙方式。您可以使用 eg __debugbreak() 或内联程序集 int 3 直接触发崩溃或断点。这将导致程序立即中断调试器,默认情况下,如果没有附加调试器,大多数 MSVC 程序将转储内核。

【讨论】:

+1 表示如果您想确保发生崩溃,这是一种相当合资的方式来引发崩溃。【参考方案3】:

除非您在我们没有看到的线程之后还有更多工作要做,否则我认为没有理由将其放在单独的线程中。我猜主线程出于某种原因抓住了它。我宁愿在它发生时抓住它,然后让它亲自渗透到顶部。

为什么会导致服务器崩溃?对我来说,这听起来像是一个糟糕的设计选择。

【讨论】:

如果您需要测试您的事后转储程序和错误报告基础架构,该怎么办?一种按需崩溃进程的方法肯定很方便。 @0A0D:看起来这很可能是某些单元测试基础设施的一部分。 :) @quixoto:对我来说更像是集成测试 @0A0D:即使在生产服务器中也可以,只要使用崩溃服务器命令的权限受到适当限制。自然不想免费进行 DOS 攻击。 如果是用于单元测试,你会希望它进入 SEH。

以上是关于与主线程相比,在辅助线程上崩溃是不是有优势?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Java中运行与主线程分开的线程?

[转]QT子线程与主线程的信号槽通信-亲测可用!

与仅使用自制线程相比,使用 AnimationTimer 是不是具有性能优势?

delphi VCL显示问题 分线程与主线程的同步

将工作线程与主线程同步

Android Handler 异步调用修改界面与主线程