2013-11-26 156 views
0

考虑一个多线程的Windows服务器应用程序。对于一般性起见,我们假设所有的线程在运行相同的功能:正常终止线程

DWORD WINAPI threaded_function(LPVOID p) 
{ 
    while (TRUE) { // do things } 
} 

而且,让我们假设我们保持引用所有这些线程。 优雅终止的最佳做法是什么? (请记住,作为一个服务,我们有着一个未知数量的服务和任何种类的进程终止方法中的过程是没问题的)

我最好的猜测是:

  1. 涂改在while (TRUE)声明,与while(global_event.not_signaled())where global_event是包裹Win32Event对象,并呼吁该方法的类的实例是显而易见的)

  2. 现在,实现终端功能如下:

    global_event.set();睡眠(/ *在这里等候什么时间?* /); thread_container.terminate_all();

我们的限制,是应用程序最终必须完成这一切线程的执行,并释放它的所有虚拟机和中资源是线程的内核对象。

有没有更好的方法来做到这一点?指定方法有缺点吗?

+0

一个常用的方法是测试每个线程标志并在设置后退出函数。使用窗口循环并退出WM_QUIT消息是实现它的一种方法。 –

+1

作为一个方面说明:如果'//做的事情'很长,那么如果可以停止执行中间代码,则可能需要在整个代码的各个点检查'global_event'。否则,您必须等待完整的循环体完成。 – crashmstr

+1

没有合理的时间等待。如果后台线程无法关闭,您别无选择,只能终止该进程。终止线程只会破坏数据。 –

回答

1

您可以创建一个互斥体,并把它的调用者线程上,如:

void caller(){ 
HANDLE mutex; 
CreateMutex(mutex); 

WaitForSingleObject(mutex); // take the mutex ownership 

createThread(threadedfunction, mutex); 

// do things 

ReleaseMutex(mutex); 

//end 
} 

并在您threadedfunction等待等的剥离:

void threadefunction(HANDLE mutex){ 

    while(WaitForSingleObject(mutex,1)==WAIT_TIMEOUT){ 
    // do things 
    } 
    ReleaseMutex(mutex); 
} 

这样你threadedfunction将保持乳宁而无法使用互斥锁时,waitforsingleobject将以1毫秒的等待超时,然后执行操作,直到它可以接受互斥锁并退出。

+1

在终止时发出的等待事件比较常见,只是更有意义,而不是超时自己的互斥量。 –

+0

但是如何在事件未发出信号时继续运行流程?如果我正在等待用WaitForSingleObject(INFINITE)发送信号,那么在等待的时候没有运行别的东西... –

+1

显然,你不会使用'INFINITE',你会使用超时而不是,如果等待在事件报告'WAIT_OBJECT_0'上。 –