终止摆好不使用TerminateThread线程() [英] Terminating a thread gracefully not using TerminateThread()

查看:138
本文介绍了终止摆好不使用TerminateThread线程()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序创建一个线程,并在后台所有的时间运行。我只能手动终止线程,而不是从线程的回调函数中。
目前我使用 TerminateThread()杀死线程,但它是导致它有时候会被挂起。
我知道有使用事件的方式和 WaitForSingleObject的()来使线程终止优雅,但我无法找到有关的例子。

My application creates a thread and that runs in the background all the time. I can only terminate the thread manually, not from within the thread callback function. At the moment I am using TerminateThread() to kill that thread but it's causing it to hang sometimes. I know there is a way to use events and WaitForSingleObject() to make the thread terminate gracefully but I can't find an example about that.

请,这里需要code。

Please, code is needed here.

推荐答案

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

TerminateThread is a bad idea, especially if your thread uses synchronization objects such as mutexes. It can lead to unreleased memory and handles, and to deadlocks, so you're correct that you need to do something else.

典型地,一个线程终止的方法是从定义线程函数返回。主线程信号工作者线程使用事件对象或者甚至一个简单的布尔如果已选中它往往不够退出。如果工作线程与 WaitForSingleObject的等待,你可能需要将其更改为 WaitForMultipleObjects的,其中目的之一是一个事件。主线程会叫 SetEvent的和工作线程会醒来并返回。

Typically, the way that a thread terminates is to return from the function that defines the thread. The main thread signals the worker thread to exit using an event object or a even a simple boolean if it's checked often enough. If the worker thread waits with WaitForSingleObject, you may need to change it to a WaitForMultipleObjects, where one of the objects is an event. The main thread would call SetEvent and the worker thread would wake up and return.

我们真的,除非你告诉我们,你在做什么不能提供任何有用的code。根据什么工作线程在做什么,你的主线程是如何传递信息给它,它可能看起来非常不同。

We really can't provide any useful code unless you show us what you're doing. Depending on what the worker thread is doing and how your main thread is communicating information to it, it could look very different.

此外,在[现在很老] MSVC,你需要使用 _beginthreadex 而不是的CreateThread ,以避免在CRT内存泄漏。请参见 MSKB 104641#

Also, under [now very old] MSVC, you need to use _beginthreadex instead of CreateThread in order to avoid memory leaks in the CRT. See MSKB #104641.

更新:

一个使用工作者线程是作为一个计时器,以做定期的一些操作。在最简单的:

One use of worker thread is as a "timer", to do some operation on regular intervals. At the most trivial:

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 。在这种情况下,你需要两个事件,一是以使线程唤醒并做一些动作,另一个让它醒来并退出:

Another use is to do something on-demand. Basically the same, but with the timeout set to INFINITE and doing some action on WAIT_OBJECT_0 instead of WAIT_TIMEOUT. In this case you would need two events, one to make the thread wake up and do some action, another to make it wake up and quit:

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返回,而不是预期的结果之一的错误是很重要的。在以上两个例子中,我们简单地把一个错误,如果我们已经暗示放弃。

Note that it's important that the loop do something reasonable if WFSO/WFMO return an error instead of one of the expected results. In both examples above, we simply treat an error as if we had been signaled to quit.

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

You could achieve the same result with the first example by closing the event handle from the main thread, causing the worker thread get an error from WaitForSingleObject and quit, but I wouldn't recommend that approach.

这篇关于终止摆好不使用TerminateThread线程()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆