6

我对 Python 相当陌生,我的经验是通过 Siemens PSS/e 中提供的 API 在 Powerflow 建模中使用它。我有一个已经使用了几年的脚本,可以在大型数据集上运行一些模拟。

为了快速完成,我通常将输入分成多个部分,然后在 IDLE 中运行脚本的多个实例。我最近为输入添加了一个 GUI,并改进了代码以更加面向对象,创建了一个类,GUI 将输入传递给该类,然后像原始脚本一样工作。

我的问题是如何从程序本身中拆分流程而不是制作多个副本?我已经阅读了一些关于 mutliprocess 模块的信息,但我不确定如何将它应用于我的情况。本质上,我希望能够实例化 N 个相同的对象,每个对象并行运行。

我现在拥有的类(称为 Bot)传递了一组参数,并在它运行直到完成时创建一个 csv 输出。我有一个单独的代码块,在最后将各个部分组合在一起,但现在我只需要了解在我的 GUI 中点击运行后启动多个 Bot 对象的最佳方法。GUI 中有输入来指定要使用的 N 段的数量。

如果我的问题相当模糊,我提前道歉。感谢您提供的任何信息,因为我有点卡住了,不知道在哪里寻找更好的答案。

4

2 回答 2

1

创建配置列表:

configurations = [...]

创建一个采用相关配置的函数,并使用您的Bot

def function(configuration):
    bot = Bot(configuration)
    bot.create_csv()

Pool使用您想要使用的 CPU创建一个工人:

from multiprocessing import Pool
pool = Pool(3)

多次调用配置列表中每个配置的函数。

pool.map(function, configurations)

例如:

from multiprocessing import Pool
import os

class Bot:
    def __init__(self, inputs):
        self.inputs = inputs

    def create_csv(self):
        pid = os.getpid()
        print('TODO: create csv in process {} using {}'
              .format(pid, self.inputs))


def use_bot(inputs):
     bot = Bot(inputs)
     bot.create_csv()


def main():
    configurations = [
        ['input1_1.txt', 'input1_2.txt'],
        ['input2_1.txt', 'input2_2.txt'],
        ['input3_1.txt', 'input3_2.txt']]

    pool = Pool(2)
    pool.map(use_bot, configurations)

if __name__ == '__main__':
    main()

输出:

TODO: create csv in process 10964 using ['input2_1.txt', 'input2_2.txt']
TODO: create csv in process 8616 using ['input1_1.txt', 'input1_2.txt']
TODO: create csv in process 8616 using ['input3_1.txt', 'input3_2.txt']
于 2017-04-28T22:54:09.233 回答
0

如果你想让生活变得不那么复杂,你可以使用multiprocess代替multiprocessing,因为对类和在解释器中的工作有更好的支持。您可以在下面看到,我们现在可以直接使用类实例上的方法,这是不可能的multiprocessing

>>> from multiprocess import Pool
>>> import os
>>> 
>>> class Bot(object):
...   def __init__(self, x): 
...     self.x = x
...   def doit(self, y):
...     pid = os.getpid()
...     return (pid, self.x + y)
... 
>>> p = Pool()
>>> b = Bot(5)
>>> results = p.imap(b.doit, range(4))
>>> print dict(results)
{46552: 7, 46553: 8, 46550: 5, 46551: 6}
>>> p.close()
>>> p.join()

上面,我使用imap, 来获取结果的迭代器,我将把它转储到dict. 请注意,您应该在完成后关闭池以进行清理。在 Windows 上,您可能还想查看freeze_support, 以了解代码无法运行的情况。

>>> import multiprocess as mp
>>> mp.freeze_support 
于 2017-05-07T06:30:51.867 回答