题:
我可以使用multiprocessing模块与Windows上的gevent一起高效地使用吗?
场景:
我有一个基于gevent的Python应用程序在Windows上执行asynchronousI / O。 该应用程序主要是I / O绑定,但也有更高的CPU负载尖峰。 这个应用程序需要通过stdin和stdout控制一个控制台应用程序。 我不能修改这个控制台应用程序,用户将能够使用他自己的自定义的,只有基于文本(线)的通信协议是固定的。
我有一个使用subprocess和线程的工作实现,但我宁愿将整个基于subprocess的通信代码与这些线程一起移动到单独的进程中,以将主应用程序重新转换为单线程。 我打算为此使用多处理模块。
在读之前:
我一直在searchWeb,阅读一些源代码,所以我知道多处理模块正在使用基于Windows命名pipe道的Pipe实现。 一对multiprocessing.queue.Queue对象将用于与第二个Python进程进行通信。 这些队列基于Pipe实现,例如IPC将通过命名pipe道完成。
关键问题是,是否调用传入队列的get方法会阻止gevent的主循环。 这个方法有一个超时,所以我可以把它做成一个有小超时的循环,但这不是一个好的解决scheme,因为它仍然会阻止小的时间周期,损害它的低I / O延迟。
我也对如何避免Windows上使用pipe道的问题提出了一些build议,这些问题已经很严重,有时甚至是脆弱的。 我不确定基于共享内存的IPC是否可以在Windows上运行。 也许我可以包装控制台应用程序的方式,这将允许使用networking套接字,这是已知与gevent工作良好的subprocess沟通。
如果可能,请不要质疑我的主要使用案例。 谢谢。
队列的get方法真的阻塞。 在超时时使用它可能会解决你的问题,但它绝对不是一个最干净的解决方案,而且最重要的是,这将导致额外的延迟,没有任何理由。 即使没有阻塞,也不是一个好的解决方案。 仅仅因为非阻塞本身是不够的,好的异步调用/ API应该平滑地集成到正在使用的I / O框架中。 是Python的gevent,用于C的libevent或用于C ++的Boost ASIO。
最简单的解决方案是使用简单的I / O,通过产生控制台应用程序并附加到控制台输入和输出描述符。 有两个主要因素需要考虑:
然而,缺点是你将不得不启动这个应用程序,将不支持与它的并发通信,并且将不支持通过网络进行通信。 新手甚至是一个很好的例子 。
为了简单但更灵活,您可以使用TCP / IP套接字。 如果客户端和服务器都在同一台计算机上运行。 另外,一个好的操作系统将使用IPC作为底层实现,所以它会很快。 而且,如果你担心这种情况的表现,你可能根本不应该使用Python,而是看看其他技术。
即使幻想解决方案 – 使用ZeroC ICE 。 这是非常现代的技术,允许几乎无缝的进程间通信。 这是一个CORBA杀手,非常容易使用。 它被许多人大量使用,被证明是同类中最快和稳定的。 这个解决方案的优点是,你可以无缝地集成许多不同语言的程序,比如Python,Java,C ++等等。但是这需要一些时间来熟悉一个概念。 如果你决定这样做,只需花一天时间阅读低谷文件。
希望能帮助到你。 祝你好运!
你的问题已经很老了。 不过,我想推荐http://gehrcke.de/gipc–我相信 – 它将以一种非常简单的方式来处理概述的挑战。 基本上,它允许您在应用程序的任何位置(也在Windows上)集成基于多处理的子进程。 与Process
对象的交互(如调用join()
)是gevent-cooperative。 通过管道管理,它可以协同阻止进程间通信。 然而,在Windows上,IPC当前比POSIX兼容的系统效率低得多(因为非阻塞I / O是通过线程池模仿的)。 根据应用程序的IPC消息传递量,这可能或可能不重要。