简体   繁体   English

如何在类对象的python中使用multiprocess

[英]How to use multiprocess in python on a class object

I am fairly new to Python, and my experience is specific to its use in Powerflow modelling through the API provided in Siemens PSS/e. 我是Python的新手,我的经验是通过西门子PSS / e提供的API在Powerflow建模中使用的。 I have a script that I have been using for several years that runs some simulation on a large data set. 我有一个脚本,我已经使用了好几年,在大型数据集上运行一些模拟。

In order to get to finish quickly, I usually split the inputs up into multiple parts, then run multiple instances of the script in IDLE. 为了快速完成,我通常将输入分成多个部分,然后在IDLE中运行脚本的多个实例。 Ive recently added a GUI for the inputs, and have refined the code to be more object oriented, creating a class that the GUI passes the inputs to but then works as the original script did. 我最近为输入添加了一个GUI,并且已经改进了代码以使其更加面向对象,创建了一个GUI,它将GUI传递给输入但后来像原始脚本一样工作。

My question is how do I go about splitting the process from within the program itself rather than making multiple copies? 我的问题是如何从程序本身分割过程而不是制作多个副本? I have read a bit about the mutliprocess module but I am not sure how to apply it to my situation. 我已经阅读了一些关于mutliprocess模块​​的内容,但我不确定如何将它应用于我的情况。 Essentially I want to be able to instantiate N number of the same object, each running in parallel. 本质上我希望能够实例化N个相同的对象,每个对象并行运行。

The class I have now (called Bot) is passed a set of arguments and creates a csv output while it runs until it finishes. 我现在拥有的类(称为Bot)传递一组参数,并在运行时创建一个csv输出,直到它完成。 I have a separate block of code that puts the pieces together at the end but for now I just need to understand the best approach to kicking multiple Bot objects off once I hit run in my GUI. 我有一个单独的代码块,最后将这些部分组合在一起但是现在我只需要了解在我的GUI中运行后将多个Bot对象踢掉的最佳方法。 Ther are inputs in the GUI to specify the number of N segments to be used. Ther是GUI中的输入,用于指定要使用的N个段的数量。

I apologize ahead of time if my question is rather vague. 如果我的问题很模糊,我会提前道歉。 Thanks for any information at all as Im sort of stuck and dont know where to look for better answers. 感谢任何信息,因为我有点卡住,不知道在哪里寻找更好的答案。

Create a list of configurations: 创建配置列表:

configurations = [...]

Create a function which takes the relevant configuration, and makes use of your Bot : 创建一个采用相关配置的函数,并使用您的Bot

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

Create a Pool of workers with however many CPUs you want to use: 创建一个具有多个CPU的工作Pool ,但要使用多个CPU:

from multiprocessing import Pool
pool = Pool(3)

Call the function multiple times which each configuration in your list of configurations. 多次调用该功能,配置列表中的每个配置。

pool.map(function, configurations)

For example: 例如:

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

Output: 输出:

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']

If you'd like to make life a little less complicated, you can use multiprocess instead of multiprocessing , as there is better support for classes and also for working in the interpreter. 如果你想让生活稍微复杂一些,你可以使用multiprocess而不是multiprocessing ,因为有更好的类支持和解释器工作。 You can see below, we can now work directly with a method on a class instance, which is not possible with 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()

Above, I'm using imap , to get an iterator on the results, which I'll just dump into a dict . 上面,我正在使用imap ,在结果上得到一个迭代器,我将把它转换成dict Note that you should close your pools after you are done, to clean up. 请注意,完成后应关闭池,以进行清理。 On Windows, you may also want to look at freeze_support , for cases where the code otherwise fails to run. 在Windows上,如果代码无法运行,您可能还需要查看freeze_support

>>> import multiprocess as mp
>>> mp.freeze_support 

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

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