gpt4 book ai didi

Python 锁定实现(带线程模块)

转载 作者:行者123 更新时间:2023-11-28 19:32:59 25 4
gpt4 key购买 nike

这可能是一个基本问题,但我是 Python 线程编程的新手,并不完全确定正确的做法是什么。

我是否应该创建一个锁对象(全局或传递)并在需要进行锁定的任何地方使用它?或者,我是否应该在我将使用它们的每个类中创建多个锁实例。以这两个基本代码示例为例,哪个方向最好?主要区别在于第二个类 A 和 B 都使用单个锁实例,而第一个使用多个实例。

示例 1

class A():
def __init__(self, theList):
self.theList = theList
self.lock = threading.Lock()

def poll(self):
while True:
# do some stuff that eventually needs to work with theList
self.lock.acquire()
try:
self.theList.append(something)
finally:
self.lock.release()





class B(threading.Thread):
def __init__(self,theList):
self.theList = theList
self.lock = threading.Lock()
self.start()


def run(self):
while True:
# do some stuff that eventually needs to work with theList
self.lock.acquire()
try:
self.theList.remove(something)
finally:
self.lock.release()



if __name__ == "__main__":
aList = []
for x in range(10):
B(aList)

A(aList).poll()

示例 2

class A():
def __init__(self, theList,lock):
self.theList = theList
self.lock = lock

def poll(self):
while True:
# do some stuff that eventually needs to work with theList
self.lock.acquire()
try:
self.theList.append(something)
finally:
self.lock.release()



class B(threading.Thread):
def __init__(self,theList,lock):
self.theList = theList
self.lock = lock
self.start()


def run(self):
while True:
# do some stuff that eventually needs to work with theList
self.lock.acquire()
try:
self.theList.remove(something)
finally:
self.lock.release()



if __name__ == "__main__":
lock = threading.Lock()
aList = []
for x in range(10):
B(aList,lock)

A(aList,lock).poll()

最佳答案

如果您在每个类中使用单独的锁对象,那么您将面临死锁的风险,例如如果一个操作先声明 A 的锁,然后再声明 B 的锁,而另一个操作先声明 B,然后再声明 A。

如果您使用单个锁,那么当不同的操作可以并行运行时,您将强制代码进入单线程。这在 Python 中并不总是像在其他语言中那么严重(它在任何情况下都有全局锁),但是假设你在写入文件时持有全局锁 Python 会释放 GIL 但你会阻止一切否则。

所以这是一个权衡。我会说选择小锁,因为这样可以最大限度地提高并行执行的机会,但要注意一次不要申请多个锁,并且尽量不要持有锁的时间超过绝对必要的时间。

就您的具体示例而言,第一个示例完全损坏。如果您锁定 theList 上的操作,那么您必须每次都使用相同的锁,否则您不会锁定任何东西。这在这里可能无关紧要,因为 list.append 和 list.remove 无论如何都是有效的原子,但是如果您确实需要锁定对列表的访问,则需要确保每次都使用相同的锁。最好的方法是将列表和锁作为类的属性保存,并强制对列表的所有访问都通过包含类的方法。然后传递容器类而不是列表或锁。

关于Python 锁定实现(带线程模块),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2773935/

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