如何正确终止 dll 中的挂起线程?
Posted
技术标签:
【中文标题】如何正确终止 dll 中的挂起线程?【英文标题】:How to terminate a hanging thread inside a dll correctly? 【发布时间】:2009-06-17 01:30:08 【问题描述】:大家好,
我有一个包含错误的第三方库。当我调用一个函数时,它可能会挂起。库函数在 dll 中调用。我决定将调用移到线程中并等待一段时间。如果线程已完成,则 OK。如果不是 - 我应该强制终止它。
这里的简化示例:
unsigned Counter = 0;
void f()
HANDLE hThread;
unsigned threadID;
// Create the second thread.
hThread = (HANDLE)_beginthreadex( NULL, 0, DoSomething, NULL, 0, &threadID );
if (WAIT_TIMEOUT == WaitForSingleObject( hThread, 5000 ))
TerminateThread(hThread, 1);
wcout << L"Process is Timed Out";
else
wcout << L"Process is Ended OK";
CloseHandle(hThread);
wcout << Counter;
unsigned int _stdcall DoSomething( void * /*dummy*/ )
while (1)
++Counter;
_endthreadex( 0 );
return 0;
问题
-
TerminateThread()函数不建议调用。
正如我之前提到的,线程在 在 dll 中运行。如果我使用 TerminateThread() 终止线程,我的 dll 将不会使用 FreeLibrary() 甚至 FreeLibraryAndExitThread() 卸载。两个函数都挂起。
如何终止线程并保持 FreeLibrary() 正常工作?
谢谢。
【问题讨论】:
也许你应该考虑在一个单独的进程中托管 rouge dll,如果东西变成梨形就终止进程? 【参考方案1】:很遗憾,您不能随意安全地终止线程。
TerminateThread 导致线程立即终止,即使线程正在持有锁或修改某些内部状态。 TerminateThread 可能会导致您的应用程序随机挂起(如果线程持有锁)或崩溃(如果线程正在修改某些状态并且它保持不一致)
如果您不能信任 DLL 的正确行为并且这会给您带来严重的可靠性问题,您应该将调用 DLL 的代码移动到一个单独的进程中 - 终止一个进程会更安全。
【讨论】:
对突然终止线程的陷阱的深刻见解。 谢谢,我会尝试尝试您的建议。 我希望我能在处理生产系统后两次投票,因为人们认为线程可能会被终止。 即使 Windows 确实释放了线程在其令人震惊的死亡过程中可能持有的任何资源,它仍然可能会导致application-level
不一致...以上是关于如何正确终止 dll 中的挂起线程?的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 协程协程的挂起和恢复 ② ( 协程挂起 和 线程阻塞 对比 )