[英]Can't pickle instance method using Pool.map(), but I have no instance method
[英]Can't use pool.map for a class method in ROS Python
我有一个耗时的 function,它使用不同的输入 arguments 被多次调用。 我正在尝试通过使用 Python 3 中的multiprocessing
模块中的Pool
来并行化它。请参阅下面的示例代码:
#! /usr/bin/env python3
import rospy
import actionlib
import multiprocessing as mp
from actionlib_tutorials.msg import FibonacciAction, FibonacciResult
def time_taking_task(n):
# only for debugging
a, b = 0, 1
for _ in range(0, n):
a, b = b, a + b
return a
class FibonacciActionClass(object):
def __init__(self, name):
self._as = actionlib.SimpleActionServer(
name,
FibonacciAction,
execute_cb=self.cb,
auto_start=False,
)
self._as.start()
def time_taking_task(self, n):
# only for debugging
a, b = 0, 1
for _ in range(0, n):
a, b = b, a + b
return a
def cb(self, goal):
result = FibonacciResult()
result.sequence.append(0)
with mp.Pool(processes=4) as pool:
nums = pool.map(self.time_taking_task, list(range(1, goal.order + 1))) # doesn't work
# nums = pool.map(time_taking_task, list(range(1, goal.order + 1))) # works
result.sequence.extend(nums)
self._as.set_succeeded(result)
if __name__ == "__main__":
rospy.init_node("fibonacci")
server = FibonacciActionClass(rospy.get_name())
rospy.spin()
map
方法采用 function 和可迭代的 object。 time_taking_task
作为 function 有效,但self.time_taking_task
会引发以下错误:
[ERROR] [1643875827.675670]: Exception in your execute callback: cannot pickle '_thread.RLock' object
Traceback (most recent call last):
File "/opt/ros/noetic/lib/python3/dist-packages/actionlib/simple_action_server.py", line 289, in executeLoop
self.execute_callback(goal)
File "/home/user/ros_ws/src/actionlib_tutorials/scripts/fibonacci_server.py", line 34, in cb
nums = pool.map(self.time_taking_task, list(range(1, goal.order + 1)))
File "/usr/lib/python3.8/multiprocessing/pool.py", line 364, in map
return self._map_async(func, iterable, mapstar, chunksize).get()
File "/usr/lib/python3.8/multiprocessing/pool.py", line 771, in get
raise self._value
File "/usr/lib/python3.8/multiprocessing/pool.py", line 537, in _handle_tasks
put(task)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 206, in send
self._send_bytes(_ForkingPickler.dumps(obj))
File "/usr/lib/python3.8/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
TypeError: cannot pickle '_thread.RLock' object
我相信 ROS 不允许以某种方式使用 Pool。 请问有什么办法吗?
如果您想在 python 多处理子进程中运行 function,则 function 及其所有 ZDBCZE77 必须是可挑选的。 由于self
是您传递到池中的 function 的 arguments 之一,因此您的 class 似乎不可挑选。 这似乎是由于 RLock object 导致actionlib.SimpleActionServer
nit 是可选的。 有关默认情况下可选择哪些类型,请参阅此网站。
您可以尝试使用另一个库(如pathos )而不是多处理,因为它使用不同的酸洗对象方式。 Or, you could try to move your function out of your class and pass data that resides in your class and that has to be used by the function as function arguments.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.