gpt4 book ai didi

c - 不使用 TerminateThread() 优雅地终止线程

转载 作者:可可西里 更新时间:2023-11-01 12:42:34 26 4
gpt4 key购买 nike

我的应用程序创建了一个线程并一直在后台运行。我只能手动终止线程,不能从线程回调函数中终止。目前我正在使用 TerminateThread() 来终止该线程,但它有时会导致它挂起。我知道有一种方法可以使用事件和 WaitForSingleObject() 使线程正常终止,但我找不到相关示例。

拜托,这里需要代码。

最佳答案

TerminateThread 是个坏主意,尤其是当您的线程使用同步对象(如互斥体)时。它会导致未释放的内存和句柄以及死锁,因此您需要做一些其他事情是正确的。

通常,线程终止的方式是从定义线程的函数返回。主线程使用一个事件对象或一个简单的 bool 值(如果检查频率足够高的话)向工作线程发出退出信号。如果工作线程等待 WaitForSingleObject,您可能需要将其更改为 WaitForMultipleObjects,其中一个对象是一个事件。主线程将调用 SetEvent,工作线程将唤醒并返回。

除非您向我们展示您在做什么,否则我们真的无法提供任何有用的代码。根据工作线程正在做什么以及您的主线程如何向它传递信息,它看起来可能会有很大不同。

此外,在 [now very old] MSVC 下,您需要使用 _beginthreadex 而不是 CreateThread 以避免 CRT 中的内存泄漏。参见 MSKB #104641 .

更新:

工作线程的一个用途是作为“计时器”,定期执行一些操作。在最微不足道的地方:

for (;;) {
switch (WaitForSingleObject(kill_event, timeout)) {
case WAIT_TIMEOUT: /*do timer action*/ break;
default: return 0; /* exit the thread */
}
}

另一个用途是按需做一些事情。基本相同,但超时设置为 INFINITE 并在 WAIT_OBJECT_0 而不是 WAIT_TIMEOUT 上执行一些操作。在这种情况下,您需要两个事件,一个使线程唤醒并执行某些操作,另一个使线程唤醒并退出:

HANDLE handles[2] = { action_handle, quit_handle };
for (;;) {
switch (WaitForMultipleObject(handles, 2, FALSE, INFINITE)) {
case WAIT_OBJECT_0 + 0: /* do action */ break;
default:
case WAIT_OBJECT_0 + 1: /* quit */ break;
}
}

请注意,如果 WFSO/WFMO 返回错误而不是预期结果之一,则循环执行合理的操作很重要。在上面的两个示例中,我们只是将错误视为我们已收到退出信号。

您可以通过从主线程关闭事件句柄来获得与第一个示例相同的结果,从而导致工作线程从 WaitForSingleObject 获取错误并退出,但我不推荐这种方法.

关于c - 不使用 TerminateThread() 优雅地终止线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1702172/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com