【问题标题】:Python 3.6: How to spawn multiple external exe instances from function(generator) in multiprocessPython 3.6:如何在多进程中从函数(生成器)生成多个外部 exe 实例
【发布时间】:2018-09-03 08:08:52
【问题描述】:

如何以多处理方式从函数(生成器)for x1 in x: 生成多个并行外部 exe 实例(以保持每个 cpu 线程始终运行一个 exec)?如果在下面的当前伪代码中没有方法可以做到这一点,那么其他最好/简单的解决方案是什么?

顺便说一句,在执行实例退出后,我需要获取输出文件的大小并删除它。 代码目的是找到 x/y/z 参数的理想组合,

os.system 行语法不正确以提高可读性。在state_x = x1/z1 后面会有更多的代码,比如exitcode check、getfilesize 和compare,所以x1x2x3 不会总是传递给变量。

x = list(range(1, 300+1))
y = list(range(1, 300+1))
z = list(range(1, 300+1))

state_x = []
state_y = []
state_z = []

import os
for x1 in x:
    for y1 in y:
        for z1 in z:
            os.system("external.exe -x1 -y1 -z1 outfile_x1_y1_z1.out")
            state_x = x1
            state_y = y1
            state_z = z1

更新1

我将代码简化为更易于理解,将os.system("external.exe... 替换为print,以便从shell 输出中更清楚代码的作用。

忽略 state_* = [] 变量总是从生成器获取最后一个循环变体,它只是简化的代码和预期的结果 - 表明代码有效!

问题还是一样,如何在循环生成器的多进程中生成 exec/print。

x = list(range(1,2+1))
y = list(range(3,4+1))
z = list(range(5,6+1))

state_x = []
state_y = []
state_z = []

import os
for x1 in x:
    for y1 in y:
        for z1 in z:
            print (x1,y1,z1)
            state_x = x1
            state_y = y1
            state_z = z1

外壳输出:

==================== RESTART: D:/Python36-32/myscript5.py ==============
1 3 5
1 3 6
1 4 5
1 4 6
2 3 5
2 3 6
2 4 5
2 4 6
>>> state_x
2
>>> state_y
4
>>> state_z
6
>>> 

更新 2:

如果从 IDLE 运行,下面的这段代码将启动外部 exe 多处理,但我没有得到变量 state_x state_y state_z 从函数传递到全局变量。代码完成后,我在 Python Shell 中输入 state_x,我得到返回空的 []

代码:

import itertools
import multiprocessing
import os

x = list(range(1,2+1))
y = list(range(3,4+1))
z = list(range(5,6+1))

state_x = []
state_y = []
state_z = []

def do_work(x1, y1, z1):
    os.system("ping.exe 127.0.0.1 -n "+str(x1)+"")
    global state_x  
    state_x = x1
    global state_y 
    state_y = y1
    global state_z

if __name__ == "__main__":
    with multiprocessing.Pool() as pool:
        results = pool.starmap(do_work, itertools.product(range(1,3),range(3,5),range(5,7), repeat=1))

【问题讨论】:

  • 你读过the official docs吗?
  • @Niayesh Isky 当然,还有数百个 SO 帖子和十几个视频教程,尝试在其他论坛和 irc #python 频道提问。

标签: python python-3.x multiprocessing generator external-process


【解决方案1】:

如果您希望每个 CPU 一个进程,通常最好的方法是使用multiprocessing.Pool。我认为这应该大致符合您的要求(您的代码逻辑的确切细节并不明显,因为您在每次迭代时都会覆盖 state_x/y/z,而不是明显效果)。

import itertools
import multiprocessing

def do_work(x, y, z):
    # do your per-job stuff here, e.g. make the os.system() call, or whatever

    return result # return whatever value you need the worker to send to the main process

if __name__ == "__main__":
    with multiprocessing.Pool() as pool:
        results = pool.starmap(do_work, itertools.product(range(1, 301), repeat=3))

    # do stuff with results here

默认情况下,不带参数创建的Pool 将为每个 CPU 内核创建一个进程。如果您愿意,可以告诉它使用不同数量的进程,但在大多数情况下,这不是必需的。

【讨论】:

  • 代码是生成器,它产生 270 万(300*300*300)个结果,而 return result 可以产生单个结果,所以它不适合。 (range(1, 301), repeat=3) 将只有 903 次重复...阅读第一篇文章中的最后一句话,state_x/y/z 不会在每次迭代中被覆盖。
  • 我想我不知道你在做什么。我的itertools.product 输出应该完全等同于您显示的嵌套循环。请给出一些在某种程度上与您的实际问题相关的示例代码。
  • @Blckknght 对不起,我的初学者一开始对此感到困惑,现在早上它是有道理的。 productfor 执行完全相同的循环,因此它按预期在多进程中启动 exe,至少目前在 IDLE 中,但它不会将局部变量从函数传递给全局变量,并且它不会从 .py 运行.请查看第一篇文章中的 UPDATE2。
  • 当我卸载 Python 2.7 时,.py 开始从 cmd.exe 运行且没有错误。仍在试图弄清楚为什么它不传递变量。
猜你喜欢
  • 1970-01-01
  • 2012-12-03
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
相关资源
最近更新 更多