Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将函数作为参数传递给具有Pool.map()的进程目标_Python_Multithreading - Fatal编程技术网

Python 将函数作为参数传递给具有Pool.map()的进程目标

Python 将函数作为参数传递给具有Pool.map()的进程目标,python,multithreading,Python,Multithreading,我正在开发一个软件,用不同的方法(单线程、多线程、多进程)对一些Python脚本进行基准测试。所以我需要在不同的进程中执行相同的函数(使用相同的参数等等) 如何将要执行的函数作为参数传递给流程目标 我目前的理解是,对函数的引用无法工作,因为引用的函数对于其他进程不可见,这就是为什么我尝试使用共享内存的自定义管理器 下面是一个简化的代码: #!/bin/python from multiprocessing import Pool from multiprocessing.managers im

我正在开发一个软件,用不同的方法(单线程、多线程、多进程)对一些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
2
0
回溯(最近一次呼叫最后一次):
文件“/test.py”,第27行,在
p、 map(threadedFunction,args)#不起作用
文件“/usr/lib/python3.5/multiprocessing/pool.py”,第260行,在地图中
返回self.\u map\u async(func、iterable、mapstar、chunksize).get()
get中第608行的文件“/usr/lib/python3.5/multiprocessing/pool.py”
提升自我价值
文件“/usr/lib/python3.5/multiprocessing/pool.py”,第385行,在任务处理中
放置(任务)
文件“/usr/lib/python3.5/multiprocessing/connection.py”,第206行,在send中
self.\u发送字节(ForkingPickler.dumps(obj))
文件“/usr/lib/python3.5/multiprocessing/reduce.py”,第50行,转储
cls(buf,协议).dump(obj)
_pickle.PicklingError:无法pickle:内置项上的属性查找weakref失败

运行您的代码时,我遇到了一些不同的错误。我认为您的关键问题是将函数传递给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()
还是我完全误解了你的问题


汉努

谢谢你的回答。maFunction是在顶层定义的,我无法更改它。我找到了一种似乎“有效”的方法:。但是,对于您的解决方案(因此也是链接的解决方案),所有流程一起使用的逻辑核心不超过一个。CPU使用率停留在12.5%(我有8个逻辑核)。也许和经理有关?你会怎么做呢?事实上,这里的问题是可以重现的:不。因为使用numpy可以解决全局解释器锁?不,但numpy中有一个功能似乎将你限制在一个核心。我不久前偶然发现了它。我只是想问一下,以防这能解释你12.5%的问题。让我们接受你的答案,只是我有另一个问题,所以我要问另一个问题。谢谢你的帮助!