c++ - 如何在 Windows 中进行正确的顺序异步消息处理?

标签 c++ winapi design-patterns concurrency c++11

我有一个 Windows 应用程序需要非常快速地处理所有传入的消息,否则我想它会严重削弱系统性能。我想到的是一种为每条消息生成和加入线程的某种方法,以便按顺序处理它们。但是这种方法有严重的问题:当我生成线程并尝试加入顶级线程时,我怎么知道它是否可用于加入?当然,我可以检查它是否可连接(我使用 std::thread),但当我这样做时,它可能会变得不可连接并且线程不是互斥体——我不能只是阻止它并再次检查。所以我需要的是某种非阻塞的延迟任务池或任务查询,至少对于消息线程。同样,我可以生成等待该查询的线程并添加任务以便对其进行处理,但它真的是好的解决方案吗?

这不一定是开箱即用的东西,我可以实现任何并发模式。

inb4: Windows、WinAPI、C++11、用于线程的 std::thread。 对不起我的英语,真的没时间提高它。

谢谢你的回答,看来我在问题描述上犯了一个错误。确切地说,我只需要让 WNDPROC 尽快返回它的结果,这样下一条消息就可以从消息队列中弹出。我需要这个,因为我在发送消息时记录了时间,所以我需要快速完成它,这样它就不会影响时间测量。此外,这些消息对系统来说很紧急,我的窗口需要快速处理它们,否则会以某种方式影响性能。

再一次:我需要以某种方式将确切的消息处理移动到其他线程,现在它看起来像这样:


case WM_INPUT:
    int timestamp = PushTimeStampToAsyncTimestampQueue();
    launchLongChainOfMessageProcessing(message,timestamp);
    return 0;

我需要摆脱那个 launchLongChainOfMessageProcessing 并用类似的东西替换它


case WM_INPUT:
    int timestamp = PushTimeStampToAsyncTimestampQueue();
    std::thread processThread([]() { do_work(message, timestamp);});
    return 0;

最佳答案

在当前的 Windows 操作系统下,您会发现没有比使用 I/O 完成端口(简称 IOCP)的重叠 I/O 更快、更具可扩展性来处理大量入站消息的方法了。它具有令人难以置信的可扩展性和极其通用的特性。

IOCP 允许您定义一个线程池,并让这些线程由 IOCP 子系统管理和调度,在任何基于 IO 的系统(套接字、管道、文件、任何东西)上等待 IO 完成通知,如果您愿意,甚至可以没有基于 IO 的系统;它也构成了一个出色的工作队列分配系统)。

我提醒您不要生成线程来处理高度古怪的并发连接。您需要一个稳定的线程池,一个足够大的线程池,这样当一个线程池由于某些内核调用(例如等待事件、互斥锁等)的停顿而阻塞时,另一个线程池会立即分派(dispatch)工作。生成线程、设置和拆除上下文的成本很高,因此请避免使用它,值得庆幸的是,IOCP 是一个很好的解决方案,可以做到这一点。当有工作而其他人忙于其他工作时,它能够让另一个线程从休眠中苏醒,这一点非常出色。

如果我设置了您所描述的系统(并且考虑到,您只能通过几段关于 SO 的内容来实现您的最终目标),我会毫不犹豫地使用基于 IOCP 的解决方案。

编辑 在 OP 更新了问题之后,我很奇怪地会坚持这个答案,但是以一种相当扭曲的方式。他希望它尽快卸载该消息队列的处理。虽然我不会为我的异步传递系统选择 Windows 消息队列,但我相信他有他的理由。

但是,我坚持使用基于 IOCP 的系统来进行实际处理。吞吐量和可扩展性实在是太好了,不能不用于分布式工作系统,似乎这就是他在这里所拥有的。没有代码,但一般算法会是。

  1. 创建一个基于 IOCP 的工作组,所有线程都在等待 GetQueueCompletionStatus()。
  2. 收到每个 WM_INPUT 后,收集您需要的任何参数,构建您的“项目”以进行处理,然后使用 PostQueuedCompletionStatus() 将项目发布到基于 IOCP 的工作组(顺便说一句,这是最方便埋葬的东西在你的工作人员“发布”功能中)。
  3. 当每个线程被唤醒时,它会将一个工作“项目”交给它们来处理。
  4. 完成一个项目后,池线程返回到 GetQueueCompletionStatus()。

Web 上有大量基于 IOCP 的工作队列示例,大多数都适合这种需求。除非由狂热分子编写,否则所有这些都将具有优于您在 Windows 下可以使用的几乎任何其他东西的性能,正是因为 IOCP 如此紧密地集成到调度中。

关于c++ - 如何在 Windows 中进行正确的顺序异步消息处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12669148/

相关文章:

c++ - 加载时移除 Qt Webkit 加载光标

c++ - 执行三个嵌套 for 循环的最快方法是什么?

c++ - 代码设计: Observer pattern?

oop - 在可扩展类层次结构中实现单一职责原则的技术/模式

c++ - STL 容器上的 lambda+for_each+delete

用于生成 winexe 的 c 编译器命令

c++ - 以系统用户身份调用应用程序(Windows)

c++ - 将 int 21h 与内联汇编一起使用

design-patterns - 设计一个文件系统

c++ - XDrawString 在 Solaris 上不工作