不使用TerminateThread()正常终止线程

Uri*_*Uri 9 c windows multithreading

我的应用程序创建了一个线程,它始终在后台运行.我只能手动终止线程,而不是在线程回调函数内.目前我正在使用它TerminateThread()来杀死那个线程但它有时导致它挂起.我知道有一种方法可以使用事件WaitForSingleObject()并使线程优雅地终止,但我找不到一个关于它的例子.

请在此处输入代码.

Tim*_*ter 19

TerminateThread是一个坏主意,特别是如果你的线程使用同步对象,如互斥.它可能导致未释放的内存和句柄,以及死锁,所以你是正确的,你需要做其他事情.

通常,线程终止的方式是从定义线程的函数返回.主线程通过使用事件对象或甚至是简单的布尔值来通知工作线程退出,如果它经常被检查的话.如果工作线程等待WaitForSingleObject,您可能需要将其更改为a WaitForMultipleObjects,其中一个对象是事件.主线程将调用SetEvent,工作线程将唤醒并返回.

除非你告诉我们你在做什么,否则我们真的无法提供任何有用的代码.根据工作线程的作用以及主线程如何向其传递信息,它可能看起来非常不同.

此外,在[现在非常旧的] 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 */
    }
}
Run Code Online (Sandbox Code Playgroud)

另一个用途是按需做一些事情.基本相同,但设置超时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;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果WFSO/WFMO返回错误而不是预期结果之一,则循环执行合理的操作非常重要.在上面的两个例子中,我们只是将错误视为已经发出信号以便退出.

通过从主线程关闭事件句柄,您可以通过第一个示例获得相同的结果,导致工作线程从中获取错误WaitForSingleObject并退出,但我不建议使用该方法.