运行 在 Cap'n Proto RPC 服务器中定期运行
Run function periodically in Cap'n Proto RPC server
我有一个 Cap'n Proto RPC 服务器,它在 window 中运行一些 OpenGL 命令。我对 window 的事件根本不感兴趣,但为了避免在 Windows 上被杀,我需要大约每秒轮询一次事件。我怎样才能以简单的方式做到这一点?
我了解到您可以创建自己的 EventPort,但我不知道如何实际使用 EventPort。当我实际上对这些事件不感兴趣时,它也可能有点矫枉过正。如果可能的话,我想优先考虑 RPC 事件而不是轮询 window。
使用 EZ-rpc 以外的东西并不是缺点,因为我想稍后转向共享内存通信。
因此,Windows 事件处理中存在这个严重缺陷:处理网络 I/O 的最佳方式是通过 I/O 完成端口 (IOCP),尤其是对于许多连接。然而,不幸的是,Windows 无法让线程在同一线程中等待 IOCP 事件和 GUI 事件。这似乎是 Win32 API 中的一个严重设计缺陷,但几十年来一直如此。更奇怪的是,内部 NT 内核 APIs 实际上支持替代方案(具体来说,它们允许 I/O 完成事件通过 APC 传递)但微软还没有制作这些 APIs public,因此使用它们的应用程序可能会在 Windows.
的未来版本中中断
因此,基本上有两种方法可以设计同时进行网络 I/O 和实现 GUI 的程序:
使用基于 MsgWaitForMultipleObjectsEx
的事件循环而不是 IOCP。你会被限制在不超过64个连接,事件循环会比较低效。
网络和 GUI 有单独的线程。
对于您的用例,听起来 #1 可能没问题,但还有另一个问题:KJ 事件循环库(由 Cap'n Proto 使用)尚未实现这种情况。它只实现基于 IOCP 的网络。在 kj/async-win32.h
中定义了一个 class Win32WaitObjectThreadPool
用于处理 GUI 事件循环方法......但目前尚未实现。 (如果您想贡献,欢迎 PR!)
如果您真的不关心及时处理 GUI 事件,那么也许可以使用 hack:您可以使用 kj::Timer
创建一个等待一秒钟的循环,然后检查 Win32 GUI 事件队列,然后再次等待,依此类推。这真的很难看,但可能很容易实现。我不确定 kj::Timer
是否通过 EZ-rpc 公开,因此您可能不得不转而使用 kj::setupAsyncIo()
等较低级别的构建块。
我有一个 Cap'n Proto RPC 服务器,它在 window 中运行一些 OpenGL 命令。我对 window 的事件根本不感兴趣,但为了避免在 Windows 上被杀,我需要大约每秒轮询一次事件。我怎样才能以简单的方式做到这一点?
我了解到您可以创建自己的 EventPort,但我不知道如何实际使用 EventPort。当我实际上对这些事件不感兴趣时,它也可能有点矫枉过正。如果可能的话,我想优先考虑 RPC 事件而不是轮询 window。
使用 EZ-rpc 以外的东西并不是缺点,因为我想稍后转向共享内存通信。
因此,Windows 事件处理中存在这个严重缺陷:处理网络 I/O 的最佳方式是通过 I/O 完成端口 (IOCP),尤其是对于许多连接。然而,不幸的是,Windows 无法让线程在同一线程中等待 IOCP 事件和 GUI 事件。这似乎是 Win32 API 中的一个严重设计缺陷,但几十年来一直如此。更奇怪的是,内部 NT 内核 APIs 实际上支持替代方案(具体来说,它们允许 I/O 完成事件通过 APC 传递)但微软还没有制作这些 APIs public,因此使用它们的应用程序可能会在 Windows.
的未来版本中中断因此,基本上有两种方法可以设计同时进行网络 I/O 和实现 GUI 的程序:
使用基于
MsgWaitForMultipleObjectsEx
的事件循环而不是 IOCP。你会被限制在不超过64个连接,事件循环会比较低效。网络和 GUI 有单独的线程。
对于您的用例,听起来 #1 可能没问题,但还有另一个问题:KJ 事件循环库(由 Cap'n Proto 使用)尚未实现这种情况。它只实现基于 IOCP 的网络。在 kj/async-win32.h
中定义了一个 class Win32WaitObjectThreadPool
用于处理 GUI 事件循环方法......但目前尚未实现。 (如果您想贡献,欢迎 PR!)
如果您真的不关心及时处理 GUI 事件,那么也许可以使用 hack:您可以使用 kj::Timer
创建一个等待一秒钟的循环,然后检查 Win32 GUI 事件队列,然后再次等待,依此类推。这真的很难看,但可能很容易实现。我不确定 kj::Timer
是否通过 EZ-rpc 公开,因此您可能不得不转而使用 kj::setupAsyncIo()
等较低级别的构建块。