简体   繁体   English

在 Python 中使用不同的可执行文件运行多处理池

[英]Running multiprocessing pool with a different executable in Python

Is it possible to run a multiprocessing pool (or a subprocess) with a different executable than the main process in Python?是否可以使用与 Python 中的主进程不同的可执行文件来运行多处理池(或子进程)?

The use case I have in mind is running some one-off tests in parallel using different virtualenvs at the same time, for gathering some data for different library versions.我想到的用例是同时使用不同的 virtualenv 并行运行一些一次性测试,以收集不同库版本的一些数据。

The issues I can forsee is that pickling/sharing things between subprocesses this way might not be trivial, as the library versions could be different.我可以预见的问题是,以这种方式在子进程之间进行酸洗/共享可能并非易事,因为库版本可能不同。 However, simple data types (lists, dicts) will probably work.但是,简单的数据类型(列表、字典)可能会起作用。

multiprocessing.spawn() supports changing the interpreter, but not concurrently. multiprocessing.spawn()支持更改解释器,但不能同时更改。

If that's a problem, just a subprocess with stdin and stdout in binary mode and schlepping a pickle up and down the pipe (that sounded wrong) should do the trick... This assumes the parent is running Python 3.如果这是一个问题,那么只有一个带有二进制模式的stdinstdoutsubprocess进程,并且在管道上上下放一个泡菜(听起来是错误的)应该可以解决问题......这假设父进程正在运行 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()

outputs产出

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)}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM