异步任务队列设计
本主题介绍与 Microsoft 游戏开发工具包 (GDK) 异步设计模式一起使用的 Microsoft 游戏开发工具包 (GDK) 任务队列。 任务队列是用于排队工作和完成任务回调的 API。 可以在几种不同的调度模式之一中配置任务队列,这些模式中包括手动调度机制,如果你想要仔细管理游戏工作负载,则可使用它们。
任务队列 API 概述
任务队列是合成的两个队列端口:一个工作端口和一个完成端口。 这些端口被绑定到同一个对象中,因为你经常需要这两个端口:用于执行异步工作的工作端口和用于告知用户相关情况的完成端口。
任务队列描述如下。
包含两个任务队列端口。
每个任务队列端口都可以有自己的调度模式,调度模式可指示如何调度队列中的项目。
调度模式既可以是通过系统线程池完全自动调度,也可以是完全手动调度,此时必须明确删除任务。
可以将回调提交到任一队列端口。
队列表示为句柄。 可以复制句柄,这可以从本质上增加队列的引用计数。
你可以通过指定调度模式独立配置每个任务队列端口。 调度模式用于确定在端口排队的回调的处理方式。 调度模式有几下几种。
线程池:在系统线程池上执行在线程池队列排队的回调。 线程池并行调取调用,在线程池线程可用时依次从队列中提取要执行的调用。
序列化线程池:回调在队列中排队并在线程池上运行,但是一个接一个地运行,而不是在所有线程池线程上并行运行。
手动:在手动队列排队的回调不会自动调度。 你可以在任何想要的线程上调度它们。 如果使用手动任务队列,必须确保同时抽取 Windows 消息队列。
立即:立即调度模式根本不用排队。 它会立即在提交回调的线程上执行调用。
任务队列句柄是可共享的资源。 关闭句柄将释放对该队列的引用。 在释放所有引用之后,队列实际上才会被销毁。
XTaskQueueDuplicateHandle
、XTaskQueueSubmitCallback
、XTaskQueueSubmitDelayedCallback
和 XTaskQueueCreateComposite
都可对队列句柄添加引用。 这意味着在完成所有回调之后,队列实际上才会被销毁。
任务队列句柄是每个进程的资源,所以无法在进程之外封送或使用。
使用模式
任务队列的典型使用模式如下。
创建任务队列句柄并指定每个端口的调度模式。
如果使用手动调度,则建立特定于应用的线程以调用队列的调度功能。
使用队列作为 Microsoft Game Development Kit (GDK) 调用的参数,或使用
XTaskQueueCallback
直接提交。(可选)在应用关闭时终止任务队列。
异步任务队列操作说明主题
本部分提供常见异步任务队列方案的操作示例。
本部分内容
创建线程池任务队列
此示例显示的是怎样创建一个任务队列,该队列在系统线程池上调度工作回调和完成回调。
提交回调
提供一个示例,该示例显示如何将回调提交到任务队列的工作端口或完成端口。
复制任务队列句柄
提供了一个示例,该示例演示如何复制任务队列句柄。 如果你有长时间运行的工作,可能希望在工作期间复制任务队列句柄。 这样,任何调用 XTaskQueueCloseHandle
的用户都不会在你仍需要相应队列时关闭该队列。
创建手动任务队列
提供一个示例,说明如何创建手动抽取的任务队列。 它将创建两个 STL 线程,调度用于工作端口和完成端口的调用。
使用事件来控制手动队列调度
提供了一个示例,此示例显示了如何使用任务队列来在其具有要调度的项时指示一个条件变量。
使用带有 Windows 消息循环的任务队列
提供示例,示例使用线程池来执行工作,但将完成端口回调集成到 Win32 窗口进程中。 此示例还演示了在将某一任务队列与其他线程模型集成时如何正确终止任务队列。
使用进程任务队列
提供显示如何使用进程任务队列的示例。 默认进程任务队列将线程池用于工作和完成调度。
创建复合任务队列
提供一个使用线程池进行工作但将完成端口回调集成到 Win32 WindowProc 回调函数中的示例。 此示例还演示了在将某一任务队列与其他线程模型集成时如何正确终止任务队列。
使用延迟回调
提供一个示例,显示如何使用延迟回调,每 500 毫秒调用 10 次回调。 将来通过 XTaskQueueSubmitDelayedCallback
API,使用任务队列将来提交回调。 通过这种方法,可以在暂短延迟后重试失败调用,或将它作为定期事件的低廉计时器。
使用任务队列等待程序
提供显示如何使用任务队列等待程序的示例。 您可将一个 Win32 内核句柄注册到任务队列。 该句柄收到信号时,将您的回调提交给队列。