计算并行函数调用python

时间:2018-01-17 22:33:23

标签: python locking multiprocessing joblib

我遇到一个问题,我需要并行调用类的实例函数并计算它被调用的次数,这样每个调用都有一个唯一的标识符(用于将结果存储在一个唯一的位置)。

Here is a question with solutions for what I want but in Java

这是一个最小的例子:

para2.py,它设置所有实例方法的酸洗东西(不太相关):

from copy_reg import pickle
from types import MethodType
from para import func

def _pickle_method(method):
    return _unpickle_method, (method.im_func.__name__, method.im_self, method.im_class)

def _unpickle_method(func_name, obj, cls):
    return cls.__dict__[func_name].__get__(obj, cls)

pickle(MethodType, _pickle_method, _unpickle_method)

func()

现在para.py包含:

from sklearn.externals.joblib import Parallel, delayed
from math import sqrt
from multiprocessing import Lock

class Thing(object):

    COUNT = 0
    lock = Lock()

    def objFn(self, x):
        with Thing.lock:
            mecount = Thing.COUNT
            Thing.COUNT += 1

        print mecount

        n=0
        while n < 10000000:# add a little delay for consistency
            n += 1
        return sqrt(x)

def func()
    thing = Thing()

    y = Parallel(n_jobs=4)(delayed(thing.objFn)(i**2) for i in range(10))
    print y

现在在终端中运行python para2.py

0
0
0
0
1
1
1
1
2
2
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]

我需要垂直方向上的这些数字计为0到9,但似乎所有四个进程仍在访问并尝试同时更新COUNT。我怎样才能做到我想要的呢?

1 个答案:

答案 0 :(得分:0)

通过多处理,python会分叉您的代码并创建一个运行代码的子进程。这样做会为每个子进程创建一个类的副本。它不共享代码/数据。您可以通过放置打印注释(如...

)来稍微调试一下

print multiprocessing.current_process().name

在您的构造函数和objFn中,查看哪些内容以及它的值是什么。

为了在进程之间共享数据,您需要从multiprocessing库中为此设计一些内容。这些是Value and Array个对象。这些使用共享内存,因此通常仅限于整数ctypes,而不仅仅是任何通用的python对象。