加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 07:51:31 所属栏目:百科 来源:网络整理
导读:我的应用程序创建一个线程,并且始终在后台运行.我只能手动终止线程,而不能从线程内回调函数. 目前我正在使用TerminateThread()来杀死那个线程,但是它有时会被挂起. 我知道有一种方法可以使用事件和WaitForSingleObject()使线程正常终止,但是我找不到一个例子
我的应用程序创建一个线程,并且始终在后台运行.我只能手动终止线程,而不能从线程内回调函数.
目前我正在使用TerminateThread()来杀死那个线程,但是它有时会被挂起.
我知道有一种方法可以使用事件和WaitForSingleObject()使线程正常终止,但是我找不到一个例子.

请,这里需要代码.

解决方法

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

通常,线程终止的方式是从定义线程的函数返回.主线程通过事件对象或者一个简单的布尔值来表示工作线程退出,如果它经常被检查.如果工作线程与WaitForSingleObject等待,您可能需要将其更改为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 */
    }
}

另一个用途是按需要做一些事情.基本上相同,但超时设置为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中获取错误并退出,但我不会推荐该方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读