繁体   English   中英

ROS Python 中的 class 方法不能使用 pool.map

[英]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.

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