等待win32线程 [英] Waiting win32 threads

查看:227
本文介绍了等待win32线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个完全线程安全的FIFO结构( TaskList )来存储任务类,多个线程,其中一些创建和存储任务,其他进程处理任务。 TaskList 类有一个 pop_front()方法,如果有至少一个返回第一个任务。否则返回 NULL

下面是一个处理函数的示例:

I have a totally thread-safe FIFO structure( TaskList ) to store task classes, multiple number of threads, some of which creates and stores task and the others processes the tasks. TaskList class has a pop_front() method which returns the first task if there is at least one. Otherwise it returns NULL.
Here is an example of processing function:

TaskList tlist;

unsigned _stdcall ThreadFunction(void * qwe)
{
    Task * task;
    while(!WorkIsOver) // a global bool to end all threads.
    {
        while(task = tlist.pop_front())
        {
            // process Task
        }
    }
    return 0;
}



我的问题是,有时,任务列表中没有新任务,因此处理线程进入无限循环( while(!WorkIsOver)),并且CPU负载增加。不知何故,我必须让线程等待,直到一个新的任务存储在列表中。我想到挂起和恢复,但然后我需要额外的信息,哪些线程正在挂起或运行,这会给编码带来更大的复杂性。

My problem is, sometimes, there is no new task in the task list, so the processing threads enters in an endless loop (while(!WorkIsOver)) and CPU load increases. Somehow I have to make the threads wait until a new task is stored in the list. I think about Suspending and Resuming but then I need extra info about which threads are suspending or running which brings a greater complexity to coding.

任何想法?

PS。我使用winapi,而不是Boost或TBB线程。因为有时我必须终止线程处理太长时间,并立即创建新的。这对我很重要。请不要建议任何这两个。

PS. I am using winapi, not Boost or TBB for threading. Because sometimes I have to terminate threads that process for too long, and create new ones immediately. This is critical for me. Please do not suggest any of these two.

感谢

推荐答案

假设您在DevStudio中开发可以使用[IO完成端口]获得所需的控制。

Assuming you are developing this in DevStudio, you can get the control you want using [IO Completion Ports]. Scary name, for a simple tool.


  • 首先,创建一个IOCompletion端口: CreateIOCompletionPort

  • 使用_beginthreadex / CreateThread创建工作线程池

  • 在每个工作线程中,实现一个循环,调用 GetQueuedCompletionStatus - 返回的lpCompletionKey将指向要处理的工作项。

  • 现在,每当您获取一个工作项进行处理时:call PostQueuedCompletionStatus 从任何线程 - 传递指针到您的工作项作为完成键参数。

  • First, create an IOCompletion Port: CreateIOCompletionPort
  • Create your pool of worker threads using _beginthreadex / CreateThread
  • In each worker thread, implement a loop that calls GetQueuedCompletionStatus - The returned lpCompletionKey will be pointing to a work item to process.
  • Now, whenever you get a work item to process: call PostQueuedCompletionStatus from any thread - passing in the pointer to your work item as the completion key parameter.

就是这样。 3 API调用,并且已经实现了基于内核实现的队列对象的线程池机制。每次调用PostQueuedCompletionStatus将自动反序列化到一个线程池线程,该线程阻塞在GetQueuedCompletionStatus。工作线程池是由您创建和维护的,因此您可以在任何耗用时间过长的工作线程上调用TerminateThread。甚至更好 - 根据它的设置,内核只会根据需要唤醒很多线程,以确保每个CPU内核以〜100%的负载运行。

Thats it. 3 API calls and you have implemented a thread pooling mechanism based on a kernel implemented queue object. Each call to PostQueuedCompletionStatus will automatically be deserialized onto a thread pool thread thats blocking on GetQueuedCompletionStatus. The pool of worker threads is created, and maintained - by you - so you can call TerminateThread on any worker threads that are taking too long. Even better - depending on how it is set up the kernel will only wake up as many threads as needed to ensure that each CPU core is running at ~100% load.

NB。 TerminateThread真的不是一个合适的API使用。除非你真的知道你在做什么,线程将泄漏它们的堆栈,线程上的代码分配的内存都不会被释放,等等。 TerminateThread实际上只在进程关闭期间有用。有一些关于网络的文章详细介绍了如何释放已知的操作系统资源,每次调用TerminateThread时泄漏 - 如果你坚持这种方法,你真的需要找到和阅读它们,如果你还没有。

NB. TerminateThread is really not an appropriate API to use. Unless you really know what you are doing the threads are going to leak their stacks, none of the memory allocated by code on the thread will be deallocated and so on. TerminateThread is really only useful during process shutdown. There are some articles on the net detailing how to release the known OS resources that are leaked each time TerminateThread is called - if you persist in this approach you really need to find and read them if you haven't already.

这篇关于等待win32线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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