我有一个Cap'n Proto RPC服务器,该服务器在窗口中运行一些OpenGL命令。我对窗口的事件完全不感兴趣,但是为了避免在Windows上被杀死,我需要每秒轮询一次事件。我该如何简单地做到这一点?
我读到您可以创建自己的EventPort,但我不知道如何实际使用EventPort。当我实际上对事件不感兴趣时,这可能也太过分了。如果可能,我想将RPC事件优先于轮询窗口。
使用EZ-rpc之外的其他东西并不是坏处,因为我想稍后再转向共享内存通信。
答案 0 :(得分:1)
因此,Windows事件处理中存在一个关键缺陷:处理网络I / O的最佳方法(尤其是在许多连接中)是通过I / O完成端口(IOCP)。但是,不幸的是,Windows无法为线程提供等待该线程中的IOCP事件和GUI事件的方法。在Win32 API中,这似乎是一个严重的设计缺陷,但数十年来一直如此。仍然奇怪的是,内部NT内核API实际上确实支持另一种方法(特别是,它们允许通过APC传递I / O完成事件),但是Microsoft尚未公开这些API,因此使用它们的应用程序将来可能会中断。 Windows版本。
结果,从本质上讲,有两种方法可以设计一种同时执行网络I / O和实现GUI的程序:
使用基于MsgWaitForMultipleObjectsEx
的事件循环代替IOCP。您将被限制为最多64个连接,并且事件循环的效率相对较低。
具有用于网络和GUI的单独线程。
在您的用例中,听起来似乎#1可能很好,但是还有另一个问题:KJ事件循环库(由Cap'n Proto使用)尚未实现这种情况。它仅实现基于IOCP的网络。 Win32WaitObjectThreadPool
中定义了一个类kj/async-win32.h
,用于处理GUI事件循环方法……但是目前尚未实现。 (如果您愿意捐款,我们欢迎PR!)
如果您真的不关心及时处理GUI事件,那么可能会发生黑客行为:您可以使用kj::Timer
创建一个等待一秒钟的循环,然后检查Win32 GUI事件排队,然后再次等待,依此类推。这确实很丑陋,但可能很容易实现。我不确定kj::Timer
是否通过EZ-rpc公开,因此您可能不得不去像kj::setupAsyncIo()
这样的较低层次的构建块。