[英]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
所以,我的問題是雙重的:
是否可以繼承 Lock 對象來做我正在做的事情?
如果不是,那么在 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.