首页 > 解决方案 > 为什么在python中使用Locks进程时,方法无法运行?

问题描述

我正在使用锁在 Python 中处理线程。我的目标是同时运行到对象 Tracker 和 LocalMapper ,它应该将消息从跟踪器对象发送到另一个对象。但是,当我使用锁时,存在锁的方法不会启动。

该程序是:

import threading
import message_filters
from sensor_msgs.msg import Image
import rospy

class Tracking:

    def __init__(self):
        self.mMutexReset=threading.Lock()

    def GrabImage(self,image_right,image_left):
        print("I am in grap image")
        self.call_mapping()
    def Run(self):

        print("Starting of the Tracking module ...")
        image_right = message_filters.Subscriber("/kitti/camera_color_right/image_raw", Image)
        image_left = message_filters.Subscriber("/kitti/camera_color_left/image_raw", Image)    
        ts = message_filters.ApproximateTimeSynchronizer([image_right,image_left], 10, 0.5)
        ts.registerCallback(self.GrabImage)
        #rospy.spin()

    def SetLocalMapper(self,LocalMapper):
        self.mpLocalMapper = LocalMapper;


    def call_mapping(self):
        self.mpLocalMapper.display()


class LocalMapping:

    def __init__(self):

        self.mlNewKeyFrames=[]
        self.mMutextester = threading.Lock()

        self.mbAcceptKeyFrames=True
        self.mlpRecentAddedMapPoints=[]


    def Run(self):
        self.mMutextester.acquire()       
        #print("here in the maping")
        r = rospy.Rate(500)  # 10hz
        while not rospy.is_shutdown():
            p=2
            #print("iam in mapping")
        self.mMutextester.release()
    def SetTracker(self,pTracker):
        self.mpTracker = pTracker

    def display(self):
        self.mMutextester.acquire()       
        print("display")
        self.mMutextester.release()       
if __name__=='__main__':
    rospy.init_node('neuronav')
    Tracker=Tracking();
    LocalMapper=LocalMapping()
    t_track = threading.Thread(target=Tracking.Run, args=(Tracker,))
    t_track.start()
    t_locl_map = threading.Thread(target=LocalMapping.Run, args=(LocalMapper,))
    t_locl_map.start()



    Tracker.SetLocalMapper(LocalMapper);
    LocalMapper.SetTracker(Tracker)

当我从 display() 函数中删除 self.mMutextester 时,它会运行。

有人可以帮我吗?

谢谢

尤内斯

标签: pythonmultithreading

解决方案


看起来你正在创建一个死锁。

.acquire()一个地方,然后以某种方式在释放锁之前调用另一个.acquire()(来自同一个线程)。因此,“嵌套”(重入)调用永远不会完成,并且锁永远不会释放,因为它正在等待永远不会发生的返回。(并且,在这个过程中,所有其他线程最终都会停止尝试获取该锁)。

围绕线程一致的生产者/消费者队列对象重新设计您的类/职责/协作 (CRC) 。使用一些线程(生产者)将工作送入您的队列,让其他线程(消费者)取出每个工作对象,对其执行工作,并将生成的对象提供给适当的“减少”队列,在该队列中单个线程消耗它们以发布到您收集/汇总的结果(可能用于输出或数据库写入中的批处理或其他)。

(我试图浏览您的代码以查看明显的调用/依赖循环......但我不能花太多时间在上面,我觉得有很多事情发生了,我从这段代码片段中看不到) .

我非常怀疑LocalMapping.Run()获取锁,调用 ROS 模块Rate()函数,然后通过循环保持锁,然后释放它)。如果锁定是为了保护 ROS(机器人?)免受多个线程改变其状态(设置)的影响,那么我认为您需要一个对象将该锁定与应用程序的代码隔离开来......再次使用一些系统来排队在机器人上执行的操作保持对它的所有访问的连贯性。


推荐阅读