windows - 一起使用 gevent 和 multiprocessing 与子进程通信

标签 windows asynchronous multiprocessing subprocess gevent

问题:

我可以在 Windows 上以高效的方式将多处理模块与 gevent 一起使用吗?

场景:

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

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

预读:

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

关键问题是调用传入Queue的get方法会不会阻塞gevent的主循环。该方法有一个超时,所以我可以将它变成一个具有小超时的循环,但这不是一个好的解决方案,因为它仍然会在短时间内阻止 gevent,从而损害其低 I/O 延迟。

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

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

最佳答案

Queue的get方法真的很阻塞。将它与超时一起使用可能会解决您的问题,但它绝对不是最干净的解决方案,而且最重要的是,它会无缘无故地引入额外的延迟。即使它不阻塞,那也不是一个好的解决方案。仅仅因为非阻塞本身是不够的,好的异步调用/API 应该顺利地集成到使用中的 I/O 框架中。成为 Python 的 gevent、C 的 libevent 或 C++ 的 Boost ASIO。

最简单的解决方案是通过生成控制台应用程序并附加到其控制台输入和输出描述符来使用简单的 I/O。有两个主要因素需要考虑:

  • 您的客户编写客户端应用程序将非常容易。他们将不必使用任何类型的 IPC、套接字或其他代码,这对许多人来说可能是一件非常困难的事情。使用这种方法,应用程序将只从标准输入读取并写入标准输出。
  • 使用这种方法测试控制台应用程序将非常容易,因为您可以手动启动它们,在控制台中输入文本并查看结果。
  • Gevent 非常适合这里的异步读/写。

但是,缺点是您必须启动此应用程序,不支持与它的并发通信,也不支持网络通信。甚至还有一个 good example for starters .

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

即使是幻想的解决方案——使用ZeroC ICE .这是非常现代的技术,允许几乎无缝的进程间通信。它是一个 CORBA killer ,非常容易使用。它被许多人大量使用,被证明是同类产品中最快的并且非常稳定。这个解决方案的美妙之处在于你可以无缝地集成许多不同语言的程序,比如 Python、Java、C++ 等。但这需要你花一些时间来熟悉一个概念。如果您决定采用这种方式,只需花一天时间阅读文档即可。

希望对您有所帮助。祝你好运!

关于windows - 一起使用 gevent 和 multiprocessing 与子进程通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4976235/

相关文章:

Python Tkinter 多处理进展

c - 仅使用 MinGW GCC 的 undefined reference

python - 如何明确指定 Firefox for Selenium 的路径?

c++ - 多个文件的 Windows 上下文菜单 [C++]

javascript - Angular 异步数据

python - 在 python 中使用多处理创建的进程上使用 join()

c++ - 使用 Ollydbg 编辑程序

c# - 如何在 C# 控制台应用程序、.NET 4.5 中实现并发调用?

node.js - 如何等待带有异步请求的循环在 node.js 中完成?

c++ - GDB/DDD : Debug shared library with multi-process application C/C++