【问题标题】:Graceful termination of a thread优雅地终止线程
【发布时间】:2013-11-26 19:40:12
【问题描述】:

考虑一个多线程的 Windows 服务器应用程序。为方便起见,我们假设所有线程都在运行相同的函数:

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

另外,假设我们保留了所有这些线程的引用。 优雅终止的最佳实践是什么? (请记住,作为服务,我们在未知数量的服务之间共享一个进程,任何类型的进程终止方法都是不可能的)

我的最佳猜测是:

  1. while(global_event.not_signaled() )改变while (TRUE)语句(where global_event是一个包装Win32Event对象的类的实例,调用的方法很明显)

    李>
  2. 现在,实现终止函数如下:

    global_event.set(); Sleep(/* 在这里等待的合理时间是多少? */ ); thread_container.terminate_all();

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

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

【问题讨论】:

  • 一种常用的方法是测试每线程标志并在设置时退出函数。使用窗口循环并退出 WM_QUIT 消息是一种方法。
  • 附带说明:如果// do things 很长,如果可以在执行过程中停止,您可能需要检查整个代码中的global_event。否则,您必须等待完整的循环体完成。
  • 没有合理的等待时间。如果后台线程未能关闭,您别无选择,只能终止该进程。终止线程只会损坏数据。
  • @AlexandreC。讨论的应用程序不是面向窗口的,所以我不想插入不必要的符号。它对我的提议有什么好处吗?
  • @EdgarJamesluffternstat:pthread 有取消点——它们非常适合这里。但是,它们在 Windows 下不存在,窗口消息泵技巧会为您处理同步(并且您的问题已明确标记为 winapi)。

标签: c multithreading winapi


【解决方案1】:

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

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

WaitForSingleObject(mutex); // take the mutex ownership

createThread(threadedfunction, mutex);

// do things

ReleaseMutex(mutex);

//end
}

并在您的线程函数上等待发布,例如:

void threadefunction(HANDLE mutex){

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

这样,您的线程函数将在无法获取互斥锁时继续运行,waitforsingleobject 将超时等待一毫秒并执行操作,直到它可以获取互斥锁并退出。

【讨论】:

  • 在终止时发出信号的可等待事件比在拥有的互斥体上超时更常见,也更有意义。
  • 但是如何在未发出事件信号的情况下继续运行进程?如果我正在等待使用 WaitForSingleObject(INFINITE) 发出信号,则等待时不会运行其他东西...
  • 显然,您不会使用INFINITE,而是使用超时,并且只有在等待事件报告WAIT_OBJECT_0时才终止线程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 2015-06-07
  • 2012-03-16
  • 1970-01-01
  • 2019-11-10
  • 2011-01-04
  • 1970-01-01
相关资源
最近更新 更多