繁体   English   中英

是否可以在 Python 中继承 Lock() 对象? 如果没有,其他调试死锁的方法?

[英]Is it possible to subclass Lock() objects in Python? If not, other ways to debug deadlock?

所以,我有一个多线程的 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。

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

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语法与您的锁一起使用(谁不会?),所以我在其中添加了适当的上下文保护。

用法如下图:

    >>> lock = DebugLock()
    >>> with lock:
    ...     print("I'm atomic!")
    ... 
    acquired <__main__.DebugLock object at 0x7f8590e50190>
    I'm atomic!
    released <__main__.DebugLock object at 0x7f8590e50190>
    >>>

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

似乎不可能。 threading.Lock() 是工厂 function(文档)。 它调用 thread.allocate_lock() - 无法控制 Lock object 创建。 您也不能对 thread.LockType class 定义进行猴子补丁(在 thread.pi 中暴露的 class 骨架)。

>>> 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'

如果您想做 inheritance 之类的事情而不会遇到此错误,我建议您尝试

 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()

并且挂起,所以我认为它正在工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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