gpt4 book ai didi

python - RLock 中的线程 block

转载 作者:太空宇宙 更新时间:2023-11-03 16:53:15 25 4
gpt4 key购买 nike

我有这个实现:

def mlock(f):
'''Method lock. Uses a class lock to execute the method'''
def wrapper(self, *args, **kwargs):
with self._lock:
res = f(self, *args, **kwargs)
return res
return wrapper


class Lockable(object):

def __init__(self):
self._lock = threading.RLock()

我在几个地方使用它,例如:

class Fifo(Lockable):

'''Implementation of a Fifo. It will grow until the given maxsize; then it will drop the head to add new elements'''

def __init__(self, maxsize, name='FIFO', data=None, inserted=0, dropped=0):
self.maxsize = maxsize
self.name = name
self.inserted = inserted
self.dropped = dropped
self._fifo = []
self._cnt = None
Lockable.__init__(self)
if data:
for d in data:
self.put(d)

@mlock
def __len__(self):
length = len(self._fifo)
return length

...

该应用程序相当复杂,但运行良好。为了确保这一点,我一直在对正在运行的服务进行压力测试,我发现它有时(很少)在 mlock 中出现死锁。我假设另一个线程正在持有锁并且没有释放它。我该如何调试这个?请注意:

  • 很难重现:我需要几个小时的测试才能陷入僵局
  • 应用程序正在后台运行
  • 一旦死锁,我就无法再与它交互

我想知道:

  • 哪个线程持有锁?
  • 为什么不发布?我正在使用上下文管理器来获取锁,因此应该始终释放它。 bug在哪里?!

我需要什么选项来进一步调试它?

我一直在检查是否有任何方法可以知道哪个线程持有RLock,但似乎没有用于此的 API。

最佳答案

我认为没有一个简单的解决方案,但可以通过一些工作来完成。

就我个人而言,我发现以下内容很有用(尽管是在 C++ 中)。

首先创建一个 Lockable 基础,该基础使用跟踪线程与其交互。 Lockable 对象将使用额外的(非递归)锁来保护将线程 ID 映射到与其交互的字典:

  • 当线程尝试锁定时,它(锁定并)创建一个条目。
  • 当它获取锁时,它(锁定并)修改条目。
  • 当它释放锁时,它(锁定并)删除该条目。

此外,一个Lockable对象将有一个低优先级线程,很少被唤醒(每几分钟一次),并查看是否有死锁的迹象(近似于线程已经持有锁很长时间了,而至少有一个其他线程正在等待它)。

因此,线程的条目应包括:

<小时/>

问题在于,这可能会改变线程的相对计时,这可能会导致您的程序进入与正​​常情况不同的执行路径。

在这里你需要发挥创意。您可能还需要在这些(可能还有其他)操作中引入(随机)时间间隔。

关于python - RLock 中的线程 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35668979/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com