【问题标题】:Is it possible to subclass Lock() objects in Python? If not, other ways to debug deadlock?是否可以在 Python 中继承 Lock() 对象?如果没有,其他调试死锁的方法?
【发布时间】:2011-07-21 18:08:36
【问题描述】:

所以,我有一个多线程 python 程序,它目前正遭受死锁。我打算通过子类化 threading.Lock 对象来记录锁获取:

import traceback
class DebugLock(threading.Lock):
    def acquire(self):
        print >>sys.stderr, "acquired", self
        #traceback.print_tb
        threading.Lock.acquire(self)  
    def release(self):
        print >>sys.stderr, "released", self
        #traceback.print_tb
        threading.Lock.release(self)  

当我尝试运行程序时,我收到以下错误:

    class DebugLock(threading.Lock):
TypeError: Error when calling the metaclass bases
    cannot create 'builtin_function_or_method' instances  

所以,我的问题是双重的:

  1. 是否可以继承 Lock 对象来做我正在做的事情?

  2. 如果不是,那么在 python 中调试死锁的最佳方法是什么?

注意:我没有编写任何 Python 扩展。有一个类似的问题:How to debug deadlock with python? 但是,它处理编译 C++ 代码和使用 GDB,因为我的代码是纯 python,所以我不能这样做。

【问题讨论】:

    标签: python multithreading oop thread-safety deadlock


    【解决方案1】:

    您可以只使用“有锁”与“有锁”的方法,如下所示:

    import threading, traceback, sys
    class DebugLock(object):
        def __init__(self):
            self._lock = threading.Lock()
        def acquire(self):
            print("acquired", self)
            #traceback.print_tb
            self._lock.acquire()
        def release(self):
            print("released", self)
            #traceback.print_tb
            self._lock.release()
        def __enter__(self):
            self.acquire()
        def __exit__(self, type, value, traceback):
            self.release()
    

    因为您可能希望对您的锁使用with 语法(谁不会呢?),所以我在其中添加了适当的上下文保护。

    用法如下图:

    >>> 锁定 = DebugLock() >>> 带锁: ... print("我是原子的!") ... 在 0x7f8590e50190 处获取 <__main__.debuglock> 我是原子的! 发布 <__main__.debuglock object at> >>>

    【讨论】:

      【解决方案2】:

      Russ 回答了重要问题 (#2),我将回答问题 #1。

      似乎不可能。 threading.Lock() 是一个工厂函数 (documentation)。它调用 thread.allocate_lock() - 无法控制 Lock 对象的创建。您也不能对 thread.LockType 类定义(thread.pi 中暴露的类骨架)进行猴子补丁。

      >>> thread.LockType.foo = "blah"
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      TypeError: can't set attributes of built-in/extension type 'thread.lock'
      

      【讨论】:

        【解决方案3】:

        如果你想在不遇到这个错误的情况下做继承之类的事情,我建议你试试

         import traceback
         from threading import Lock
         class DebugLock():
             def __init__(self,lock = None):
                 self.lock = lock or Lock()
        
                 # normally done with __dict__
                 for command in dir(self.lock):
                     self.__dict__[command] = getattr(self.lock,command)
        

        我使用self.__dict__.update(lock.__dict__) 的正常方法似乎不起作用。我用锁定代码对此进行了测试

         X = DebugLock()
         y = X.lock
         Y = DebugLock(y)
         X.acquire()
         Y.acquire()
         X.release()
         Y.release()
        

        然后挂起,所以我认为它正在工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-07-01
          • 2019-09-14
          • 1970-01-01
          • 1970-01-01
          • 2020-01-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多