首页 > 解决方案 > 在 Python 中使用不同的可执行文件运行多处理池

问题描述

是否可以运行与 Python 中的主进程不同的可执行文件的多处理池(或子进程)?

我想到的用例是同时使用不同的 virtualenvs 并行运行一些一次性测试,以收集不同库版本的一些数据。

我可以预见的问题是,以这种方式在子进程之间腌制/共享内容可能并非易事,因为库版本可能不同。但是,简单的数据类型(列表、字典)可能会起作用。

标签: pythonmultiprocessing

解决方案


multiprocessing.spawn()支持更改解释器,但不能同时更改。

如果这是一个问题,只需在二进制模式下subprocess使用stdinstdout在管道上上下放一个泡菜(听起来不对)就可以解决问题......这假设父级正在运行 Python 3。

import sys
import pickle
import subprocess
import random
import io

# Grab hold of binary I/O streams

if sys.version_info[0] == 3:
    i_stream = sys.stdin.buffer
    o_stream = sys.stdout.buffer
else:
    i_stream = sys.stdin
    o_stream = sys.stdout


def child():
    input_data = pickle.loads(i_stream.read())
    output_data = dict(
        input_data,
        random_twice=input_data["random"] * 2,
        version=tuple(sys.version_info),
    )
    o_stream.write(pickle.dumps(output_data, protocol=2))


def parent():
    # The highest protocol supported by Python 2.7 is version 2.
    input_data = pickle.dumps(
        {"hello": "world", "random": random.randint(1, 100000)},
        protocol=2,
    )
    for python in ("python2.7", "python3.7"):
        proc = subprocess.run(
            ["/usr/bin/env", python, sys.argv[0], "child"],
            check=True,
            encoding=None,
            input=input_data,
            stdout=subprocess.PIPE,
        )
        print(python, pickle.loads(proc.stdout))


if __name__ == "__main__":
    if "child" in sys.argv:
        child()
    else:
        parent()

输出

python2.7 {'random_twice': 174850, 'random': 87425, 'hello': 'world', 'version': (2, 7, 16, 'final', 0)}
python3.7 {'hello': 'world', 'random': 87425, 'random_twice': 174850, 'version': (3, 7, 6, 'final', 0)}

推荐阅读