使用Pool.map()将函数作为参数传递给进程目标

时间:2016-11-15 06:44:46

标签: python multithreading

我正在开发一种软​​件,使用不同的方法(单线程,多线程,多进程)对一些脚本Python进行基准测试。所以我需要在不同的进程中执行相同的函数(使用相同的参数等)。

如何将函数作为参数传递给进程目标?

我目前理解的是对函数的引用不起作用,因为引用的函数对于其他进程是不可见的,这就是为什么我尝试使用共享内存的自定义管理器。

这是一个简化的代码:

#!/bin/python

from multiprocessing import Pool
from multiprocessing.managers import BaseManager
from itertools import repeat

class FunctionManager(BaseManager):
    pass

def maFunction(a, b):
    print(a + b)

def threadedFunction(f_i_args):
    (f, i, args) = f_i_args
    f(*args)

FunctionManager.register('Function', maFunction)

myManager = FunctionManager()
myManager.start()

myManager.Function(0, 0) # Test 1
threadedFunction((maFunction, 0, (1, 1))) # Test 2

p = Pool()
args = zip(repeat(myManager.Function), range(10), repeat(2, 2))
p.map(threadedFunction, args) # Does not work
p.join()

myManager.shutdown()

" p.map()"当前的酸洗错误如下:

2
0
Traceback (most recent call last):
  File "./test.py", line 27, in <module>
    p.map(threadedFunction, args) # Does not work
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 260, in map
    return self._map_async(func, iterable, mapstar, chunksize).get()
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 608, in get
    raise self._value
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 385, in _handle_tasks
    put(task)
  File "/usr/lib/python3.5/multiprocessing/connection.py", line 206, in send
    self._send_bytes(ForkingPickler.dumps(obj))
  File "/usr/lib/python3.5/multiprocessing/reduction.py", line 50, in dumps
    cls(buf, protocol).dump(obj)
_pickle.PicklingError: Can't pickle <class 'weakref'>: attribute lookup weakref on builtins failed

1 个答案:

答案 0 :(得分:1)

我在运行代码时遇到了一些不同的错误。我认为你的关键问题是你将一个函数传递给FunctionManager.register()而不是一个类。我还必须删除你的zip以使其工作并手动创建一个列表,但这可能你可以解决。这只是一个例子。

以下代码可以使用您的确切结构运行并执行某些操作。我会这样做有点不同而不使用BaseManager,但我认为你有你的理由。

#!/usr/bin/python3.5

from multiprocessing import Pool
from multiprocessing.managers import BaseManager
from itertools import repeat

class FunctionManager(BaseManager):
    pass


class maClass(object):
    def __init__(self):
        pass
    def maFunction(self,a, b):
        print(a + b)

def threadedFunction(f_i_args):
    (f, i, args) = f_i_args
    f(*args)

FunctionManager.register('Foobar', maClass)

myManager = FunctionManager()
myManager.start()
foobar = myManager.Foobar()

foobar.maFunction(0, 0) # Test 1
threadedFunction((foobar.maFunction, 0, (1, 1))) # Test 2

p = Pool()
#args = list(zip(repeat(foobar.maFunction), range(10), repeat(2, 2)))
args = []
for i in range(10):
    args.append([foobar.maFunction, i, (i,2)])


p.map(threadedFunction, args) # Does now work
p.close()
p.join()

myManager.shutdown()

或者我是否完全误解了你的问题?

哈努哈利