如何在Windows中进行正确的顺序异步消息处理
How to make proper sequential async message processing in Windows?
我有一个windows应用程序,它需要非常快速地处理所有传入消息,否则我想它会严重削弱系统性能。我所想到的是一种为每条消息生成和连接线程的方法,以便按顺序处理它们。但这种方法有一个严重的问题:当我生成线程并试图加入顶级线程时,我怎么知道它是否可以加入?当然,我可以检查它是否是可连接的(我使用std::thread),但当我这样做的时候,它可能会变得不可连接,并且thread不是互斥体——我不能只是阻止它并再次检查。所以我需要的是某种非阻塞的任务池或任务查询,至少对于消息线程是这样。同样,我可以生成等待该查询的线程,并添加任务以便进行处理,但这真的是一个好的解决方案吗?
这不一定是开箱即用的东西,我可以实现任何并发模式。
inb4:Windows,WinAPI,C++11,std::线程用于线程。对不起我的英语,真的没时间提高。
谢谢你的回答,看来我在问题描述中犯了一个错误。确切地说,我只需要让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的系统;这也是一个出色的工作队列分发系统)。
我提醒您不要为处理高度偏心的并发连接而派生线程。您需要一个稳定的线程池,该线程池足够大,这样当一个线程池由于对内核的某些调用(如等待事件、互斥锁等)的暂停而阻塞时,另一个线程将立即调度工作。生成线程、设置和删除上下文是昂贵的,所以要避免它,谢天谢地,IOCP是一个很好的解决方案。当工作正在进行,而其他人正忙于其他工作时,它能让另一条线索从睡眠中苏醒过来,这一能力非常出色。
如果我建立了你所描述的系统(而且,你只能通过关于so的几段话来实现你的最终目标),我会毫不犹豫地使用基于IOCP的解决方案。
编辑在OP更新问题后,我奇怪地会支持这个答案,但方式相当扭曲。他希望它能尽快卸载对该消息队列的处理。虽然我不会为我的异步传递系统选择windows消息队列,但我相信他有他的理由。
然而,我坚持使用基于IOCP的系统来进行实际处理。吞吐量和可扩展性太好了,不能不用于分布式工作系统,这似乎就是他在这里所拥有的。没有代码,但一般算法是。
- 创建一个基于IOCP的工作组,所有线程都在等待GetQueueCompletionStatus()
- 收到每个WM_INPUT后,收集所需的任何参数,构建要处理的"项目",并使用PostQueuedCompletionStatus()将项目发布给基于IOCP的工作组(顺便说一句,这是隐藏在工作组"发布"功能中最方便的事情)
- 当每个线程被唤醒时,它会将一个要处理的工作"项"交给它们
- 处理完一个项后,池线程返回到GetQueueCompletionStatus()
网络上有大量基于IOCP的工作队列示例,大多数都可以满足这一需求。所有这些,除非是由恶魔编写的,否则都将具有比Windows下可以使用的任何其他东西都优越的性能,这正是因为IOCP与调度器紧密集成在一起。
- CMake-按正确顺序将项目与C运行时对象文件链接
- 函数调用中参数的顺序重要吗
- 为什么不;名字在地图上是按顺序排列的吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 数到第n个楼梯的路(顺序无关紧要)
- 优先顺序:智能指针和类析构函数
- 在循环中按顺序遍历成员变量
- 独立读取-修改-写入顺序
- QML按钮点击功能执行顺序
- C++中数据类型修饰符的顺序
- 当比特(而不是字节)的顺序至关重要时的持久性
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 通过选项卡的文本设置QTabWidget顺序
- c++11评估顺序(未定义的行为)
- 异步执行比顺序执行需要更长的时间
- 如何在Windows中进行正确的顺序异步消息处理
- 在 boost::asio 中启动异步操作和运行io_service的正确顺序
- 为什么C++异步按顺序运行而没有未来
- 如何用c++ boost::asio顺序执行异步操作