2015-03-25 128 views
6

我正在使用_beginthreadex函数创建线程。我传入的函数地址有一个无限循环(while(1))。我有threadidthreadhandle如何安全地关闭其中有无限循环的线程

我可以使用TerminateThread(threadhandle,1);但它是危险的。

安全的方法是使用_endthreadex杀死线程,但它只能从线程内部使用,并且我想从外部杀死线程。

因此,请建议是否有安全的方法来关闭,结束或从外部安全地使用threadidthreadhandle杀死线程。

+7

你必须修复你的代码,你需要给线程一个退出条件。如有必要,在另一个进程中运行危险且不合作的代码。 – 2015-03-25 09:25:19

+0

这是c **还是** C++,windows具体? etc ... – UmNyobe 2015-03-25 09:25:39

+0

增加了winapi标签,因为这确实是Windows特有的。 – Lundin 2015-03-25 09:28:34

回答

12

你应该 - 从字面上 - 从不使用TerminateThread()我甚至不开玩笑。如果您从外部终止线程,则保留在其中的所有资源都将被泄漏,所有在内部访问的状态变量将具有未确定的状态,依此类推。


您的问题的解决方案可能是通知您的线程完成自己。它可以通过由线程安全手段更改的volatile变量来完成(参见InterlockedIncrement()),Windows事件或类似的东西。如果你的线程有一个消息循环,你甚至可以通过发送消息让它停止。

+0

是的,我也阅读了msdn上的所有内容。但我认为,如果有办法做到这一点(从外部安全地杀死线程)。实际上修改线程内部的while循环是我最后的选择。但似乎这是唯一的选择。 – lsrawat 2015-03-25 09:37:26

+0

@Israwat - 相信我,我开发大量多线程应用程序(主要是服务器),并从外部杀死一个线程是一个非常糟糕的做法,导致极大的头痛。另外,如果你使用像MFC这样的框架,你会泄漏很多内存,因为MFC线程会为后台MFC对象保留大量内存。 – mg30rg 2015-03-25 09:40:53

+0

好吧,那么我希望我必须修改while循环......感谢您的帮助 – lsrawat 2015-03-25 09:43:31

8

正确的方法是通过使用CreateEvent创建事件“杀了我”,然后在想要杀死线程时标记此事件。而不是让你的线程等待while(1),请等待while(WaitForSingleObject(hevent_killme, 0))。然后你可以简单地让线程回调完成并返回,不需要调用_endthreadex等。回调函数的

实施例:

static DWORD WINAPI thread_callback (LPVOID param) 
{ 
    ... 
    while(WaitForSingleObject(hevent_killme, 0) != WAIT_OBJECT_0) 
    { 
    // do stuff 
    } 

    return 0; 
} 

来电:

HANDLE hevent_killme = CreateEvent(...); 
... 

void killthread (void) 
{ 
    SetEvent(hevent_killme); 
    WaitForSingleObject(hthread_the_thread, INFINITE); 
    CloseHandle(hevent_killme); 
    CloseHandle(hthread_the_thread); 
} 

从不使用TerminateThread。

+0

while(1)循环在线程函数内部。我不等待线程在无限循环中终止。 – lsrawat 2015-03-25 09:32:22

+0

@lsrawat是的,我明白了,我的答案是用这个假设写的。我会澄清一点。 – Lundin 2015-03-25 09:34:36

+0

@Israwat - 你不必这样做。伦丁建议你检查事件的状态,而不是线程。 – mg30rg 2015-03-25 09:34:55

7

而不是while(1),您可以使用while(continue_running),其中continue_runningTrue线程循环应运行时。当您要停止线程时,请将控制线程设置为continue_runningFalse。当然,确保你用互斥锁妥善保护continue_running,因为它是一个变量,它的值可以从两个线程中修改。

+2

并且记住要将'continue_running'声明为volatile,否则优化可能会破坏您的代码。 (在Visual Studio或gcc中,在其他IDE中可能有所不同) – mg30rg 2015-03-25 09:44:05

+1

@ mg30rg在大多数CPU上,布尔是原子操作 – 2015-03-25 09:45:47

+2

@ user9000 - 这不是关于布尔值,而是编译器优化。如果你的编译器不是你变量的多线程特性的话,它可能会缓存/复制/多任务/跳过/等等。它出于性能原因。 – mg30rg 2015-03-25 09:46:38