在Cap'n Proto RPC服务器中定期运行功能

时间:2018-08-16 17:26:14

标签: c++ event-loop capnproto

我有一个Cap'n Proto RPC服务器,该服务器在窗口中运行一些OpenGL命令。我对窗口的事件完全不感兴趣,但是为了避免在Windows上被杀死,我需要每秒轮询一次事件。我该如何简单地做到这一点?

我读到您可以创建自己的EventPort,但我不知道如何实际使用EventPort。当我实际上对事件不感兴趣时​​,这可能也太过分了。如果可能,我想将RPC事件优先于轮询窗口。

使用EZ-rpc之外的其他东西并不是坏处,因为我想稍后再转向共享内存通信。

1 个答案:

答案 0 :(得分:1)

因此,Windows事件处理中存在一个关键缺陷:处理网络I / O的最佳方法(尤其是在许多连接中)是通过I / O完成端口(IOCP)。但是,不幸的是,Windows无法为线程提供等待该线程中的IOCP事件和GUI事件的方法。在Win32 API中,这似乎是一个严重的设计缺陷,但数十年来一直如此。仍然奇怪的是,内部NT内核API实际上确实支持另一种方法(特别是,它们允许通过APC传递I / O完成事件),但是Microsoft尚未公开这些API,因此使用它们的应用程序将来可能会中断。 Windows版本。

结果,从本质上讲,有两种方法可以设计一种同时执行网络I / O和实现GUI的程序:

  1. 使用基于MsgWaitForMultipleObjectsEx的事件循环代替IOCP。您将被限制为最多64个连接,并且事件循环的效率相对较低。

  2. 具有用于网络和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()这样的较低层次的构建块。