Python 3.6:如何在多进程中从函数(生成器)生成多个外部exe实例

时间:2018-03-24 21:28:25

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

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

在exec实例退出后,我需要获得文件大小和输出。删除它。 代码目的是找到x / y / z参数的理想组合,

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

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

UPDATE1

我将代码更简化为更易理解,将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

Shell输出:

==================== 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
>>> 

UPDATE2:

如果从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))

1 个答案:

答案 0 :(得分:0)

如果您希望每个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核心创建一个进程。如果您愿意,可以告诉它使用不同数量的进程,但在大多数情况下它不是必需的。