2017-09-24 168 views
0

我正在实现一个Win32控制台文本编辑器,它有一个内部消息队列,用于传递有关哪些区域需要重新绘制,消息来自插件等信息。我更喜欢它默认为单线程(如果没有任何事情发生这需要额外的线程)。我考虑2种消息队列实施策略:文本编辑器是否可以将每个按键从一个线程传递到另一个线程?

  1. 使用通用队列和Win32事件,所以我可以用WaitForMultipleObjectsEx同时等待内部消息和用户输入,同时传递控制台输入句柄和事件句柄。在这种情况下,文本编辑器可以完全在一个线程内生存。
  2. 使用I/O完成端口。在这种情况下,文本编辑器至少需要两个线程,其中一个调用GetQueuedCompletionStatus来获取消息,另一个读取用户输入并通过PostQueuedCompletionStatus将其发送到队列。控制台输入句柄的原因不能重叠,并且WaitFor*函数不能接受完成端口作为等待句柄,所以不可能同时等待它们。就像在第一个设置中一样,当没有输入或事件时,两个线程都不会浪费CPU时间,但每个按键都必须通过IOCP从一个线程传递到另一个线程。

哪种设计总体上更好?

性能和延迟的缺点是将每个按键通过IOCP传递给文本编辑器很重要吗?

+0

我不知道Windows,但你每秒钟都会得到很少的按键。电脑速度很快。 –

+0

即使线程只是在内核模式下等​​待,如果您有无意义的线程,您仍然在浪费内存。 – Anders

+0

您是否考虑过使用[Qt](http://qt.io)等跨平台工具包?然后你会做什么工具包提供 –

回答

2

IOCP的性能和延迟对您而言是很好的。然而,我不会将每个按键转换为PostQueuedCompletionStatus。我宁愿让PostQueuedCompletionStatus一次排列多个按键,无论您从ReadConsoleInput得到多少数量。

我认为性能差异很小,要么环境可能更快。而WaitForMultipleObjects更容易实现。

P.S.你确定你需要消息队列吗?为什么不用任何线程处理这些重绘请求/插件消息,例如使用关键部分要防范(控制台输出+你的共享状态)?如果拥挤程度很低,比如100Hz消息+ 15Hz按键,并且您可以快速处理它们,这将使您的延迟比IOCP或任何其他队列的延迟更低:低拥塞或短暂锁定时,关键部分甚至不会切换到内核锁定/解锁。这也将简化设计,你的主线程将会阻塞ReadConsoleInput()调用,在此之前不需要WaitFor ..

+0

谢谢你的回答!我会考虑你建议的同步消息,至少对于某些类型的消息来说,它看起来好多了。有一个消息队列+ WaitFor *'/'GetQueuedCompletionStatus'的原因是可以通过Alertable I/O或IOCP分别在主线程中执行I/O操作,也不需要完全重入,这是必需的(如果我的理解是正确的),如果一切都在原地调用。 – jhkouy78reu9wx

+0

@ jhkouy78reu9wx当您​​有多个线程处理完成请求或者您有超过MAXIMUM_WAIT_OBJECTS = 64个并发流时,IOCP仅比可警告的I/O更好。如果你没有那么多的流,我的期望是WaitForMultipleObjects和IOCP一样快。 处理控制台输入与async IO在同一队列中可能很有趣:用户按下按键〜10Hz最大,异步IO可以以1 KHz或更高的速率完成,但延迟方式您希望优先处理用户输入。 WaitForMultipleObjects稍微好一些,因为它按顺序优先处理句柄。 – Soonts

相关问题