Windows 同时使用gevent和multiprocessing与子流程通信

Windows 同时使用gevent和multiprocessing与子流程通信,windows,asynchronous,multiprocessing,subprocess,gevent,Windows,Asynchronous,Multiprocessing,Subprocess,Gevent,问题: 我能否在Windows上高效地将多处理模块与gevent一起使用 情景: 我有一个基于gevent的Python应用程序在Windows上执行异步I/O。该应用程序主要受I/O限制,但也存在较高CPU负载的峰值。此应用程序需要通过其stdin和stdout控制控制台应用程序。我无法修改这个控制台应用程序,用户将能够使用自己的自定义应用程序,只有基于文本(行)的通信协议是固定的 我有一个使用子进程和线程的工作实现,但我更愿意将整个基于子进程的通信代码与这些线程一起移动到一个单独的进程中,以

问题:

我能否在Windows上高效地将多处理模块与gevent一起使用

情景:

我有一个基于gevent的Python应用程序在Windows上执行异步I/O。该应用程序主要受I/O限制,但也存在较高CPU负载的峰值。此应用程序需要通过其stdin和stdout控制控制台应用程序。我无法修改这个控制台应用程序,用户将能够使用自己的自定义应用程序,只有基于文本(行)的通信协议是固定的

我有一个使用子进程和线程的工作实现,但我更愿意将整个基于子进程的通信代码与这些线程一起移动到一个单独的进程中,以将主应用程序恢复为单线程。我计划为此使用多处理模块

预读:

我已经在网上搜索了很多次,并阅读了一些源代码,因此我知道多处理模块正在使用基于Windows上命名管道的管道实现。一对multiprocessing.queue.queue对象将用于与第二个Python进程通信。这些队列基于该管道实现,例如,IPC将通过命名管道完成

关键问题是,调用传入队列的get方法是否会阻塞gevent的主循环。该方法有一个超时,所以我可以用一个小的超时将其放入一个循环中,但这不是一个好的解决方案,因为它仍然会在很短的时间段内阻塞gevent,从而影响其较低的I/O延迟

我也愿意接受关于如何规避在窗户上使用管道的整个问题的建议,众所周知,管道很硬,有时很脆弱。我不确定基于共享内存的IPC在Windows上是否可行。也许我可以将控制台应用程序包装为允许使用网络套接字与子进程通信的方式,众所周知,网络套接字可以很好地与gevent配合使用


如果可能的话,请不要质疑我的主要用例。谢谢。

队列的get方法真的被阻塞了。将它与超时一起使用可能会解决您的问题,但它肯定不是最干净的解决方案,而且最重要的是,它会毫无理由地引入额外的延迟。即使它没有阻塞,这也不是一个好的解决方案。仅仅因为非阻塞本身是不够的,好的异步调用/API应该顺利地集成到正在使用的I/O框架中。对于Python来说是GPET,C++是BeBevor,或者是C++的Boost ASIO。 最简单的解决方案是使用简单的I/O,方法是生成控制台应用程序并附加到其控制台输入和输出描述符。有两个主要因素需要考虑:

  • 您的客户编写客户机应用程序将非常容易。他们将不必使用任何类型的IPC、套接字或其他代码,这对许多人来说可能是非常困难的事情。使用这种方法,应用程序只需从stdin读取数据并写入stdout
  • 使用这种方法测试控制台应用程序将非常容易,因为您可以手动启动它们,在控制台中输入文本并查看结果
  • Gevent非常适合异步读/写
但是,缺点是您必须启动此应用程序,不支持与它进行并发通信,也不支持通过网络进行通信。甚至还有一个

为了保持简单但更灵活,您可以使用TCP/IP套接字。如果客户端和服务器都在同一台计算机上运行。此外,一个好的操作系统将使用IPC作为底层实现,因此速度会很快。而且,若您担心本例的性能,您可能根本不应该使用Python,而应该考虑其他技术

甚至幻想解决方案——使用。这是一种非常现代的技术,允许几乎无缝的进程间通信。这是一个CORBA杀手,非常容易使用。它被许多人大量使用,被证明是同类中速度最快且岩石稳定的。这个解决方案的优点在于,可以无缝地集成许多不同语言的程序,如Python、java、C++等,但这需要一些时间来熟悉概念。如果您决定这样做,只需花一天时间阅读文档即可


希望能有帮助。祝你好运

你的问题已经很老了。尽管如此,我还是想推荐一种——我相信——能够以非常直截了当的方式应对上述挑战的方法。基本上,它允许您在应用程序的任何位置(也在Windows上)集成基于多处理的子进程。与
Process
对象的交互(例如调用
join()
)是gevent协作的。通过它的管道管理,它允许协作地阻塞进程间通信。然而,在Windows上,IPC目前的效率远远低于POSIX兼容系统(因为非阻塞I/O是通过线程池模拟的)。根据应用程序的IPC消息传递量,这可能重要,也可能不重要

谢谢你的详细回答。gevent processs.py示例的问题是,它只实现一个通信步骤。我们正在使用一个worker,它可以随时发送数据,同时我们可以向它发送命令,比如stop命令。但它不会终止子流程,它应该保持可用。但是,我将尝试集成这两个循环。这可能对Windows没有帮助,但值得一试。使用TCP/IP是我考虑的另一个选项,但它需要一个包装层,这会使事情复杂化,并使解决方案变得沉重。我来看看零碳冰。@fviktor:不客气。您可以随时使用异步I/O发送数据。您唯一需要保证的是不会并行执行多个写入。专用writer线程和一些队列帮助