【问题标题】:How to optimally use multi-threading with multi-processing in python?如何在python中以最佳方式使用多线程和多处理?
【发布时间】:2020-07-09 00:30:56
【问题描述】:

我在 Python 中创建了一个处理器类,它需要并行(或串行)执行多个可执行文件。 Processor 和 Executable 类可能如下所示:

Class Processor(object):
    executables: list() # list of Executable objects
    should_execute_in_parallel: bool
    attr1: object
    attr2: object

    def process():
        # Pre-processing
        # Execute all executables serailly/parallely based on self.should_execute_in_parallel
        # Post-processing
    

Class Executable(object):
    cmd: str  # command string to execute
    attr1: object
    attr2: object

我创建了一个 Executor 类,它接受一个可执行文件并执行它

class Executor(object):
    def __init__(self, executable):
        self.executable = executable
        # This is to demonstrate that Executor object is stateful
        self.executable_id = self._get_executable_id(self.executable)

    def execute():
        # Pre-processing (I/O bound, depends on self)
        # Launch separate process for self.executable & monitor (I/O during each monitoring phase)
        # Post-processing (I/O bound, depends on self)

我希望在 Processor.process() 中并行化 Executor.execute()。由于每个 Executor.execute() 调用都会产生一个新的 Python 进程,因此处理器级别的多处理可能会过大。因此,我正在考虑为每个 Executor 对象使用多个线程,这反过来将为相应的可执行文件生成一个新进程并继续对其进行监控。

注意:由 Executor.execute() 启动的进程需要由 Executor 对象定期监控,为此我使用了 python 警报。 I/O 发生在每个监控阶段。

  1. 在 python 中是否有推荐/最佳方式将多线程与多处理相结合(如上)?
  2. 只要 Executor.execute() 不受 CPU 限制(不包括衍生的进程),会不会有任何 GIL 问题?
  3. 如果 Executor 对象是无状态的,这里会更容易实现并行性吗?
  4. 有没有更好的方法来解决这个用例?

【问题讨论】:

    标签: python multithreading parallel-processing multiprocessing gil


    【解决方案1】:

    我认为使用单进程单线程和subprocess module from python 会更快乐。如果您的所有代码都在生成其他程序,请以非阻塞方式进行。

    【讨论】:

      【解决方案2】:

      针对您的问题,我能否提供以下答案,希望对您有所帮助!

      1. python中是否有推荐/最佳方式将多线程与多处理相结合(如上)?

      如果您在系统中调用不同的进程,请考虑使用subprocess,而subprocess 又可以从thread pool 管理的各种线程中调用。如果您确实需要独立于 GIL 的进程,请考虑使用 multiprocessing 或查看您是否应该使用像 Dask 这样的并发/分布式任务调度程序。

      2.只要 Executor.execute() 不受 CPU 限制(不包括衍生进程),会不会有任何 GIL 问题?

      GIL 总会有一些问题,除非你从你正在运行的 python 解释器中分发,这可以通过上面提到的multiprocessing 来实现。根据我的理解,当从该对象运行您的操作系统进程时,您正在使用的当前线程仍将与 GIL 交互(我相信有人可以比我更好地解释这种方式......)

      3.如果 Executor 对象是无状态的,这里会不会更容易实现并行化?

      它们在某种意义上总是有状态的,除非您将它们从它们启动的初始过程中分离出来。我认为如果你在操作系统中运行子进程,你可以多线程多个执行器并让它们运行。

      4.有没有更好的方法来解决这个用例?

      I wonder if you'd find the concurrent.futures package interesting

      我真的希望这会有所帮助,因为这对我来说是一个早期的答案,我可以通过完善我的解释来做到这一点。

      祝你好运!

      【讨论】:

      • 嗨,吉姆,感谢您的详细回答。它帮助我更好地理解这里的理论并决定如何继续我的用例。
      猜你喜欢
      • 2020-07-18
      • 1970-01-01
      • 2021-02-11
      • 2021-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 1970-01-01
      相关资源
      最近更新 更多