gpt4 book ai didi

python - python 中的线程锁无法按预期工作

转载 作者:行者123 更新时间:2023-11-28 21:54:43 25 4
gpt4 key购买 nike

我试图保护我的线程中的数据不受主线程的影响。我有以下代码:

lock = threading.Lock()

def createstuff(data):
t= threading.Thread(target=func, args=(data,))
t.start()

def func(val):
with lock:
print 'acquired'
time.sleep(2)
print ('Value: %s, : %s'%(val, threading.currentThread().getName()))
print 'released\n'

ags_list = ['x']

createstuff(ags_list)

rn =random.randint(5,50)
print 'random no:', rn
ags_list[0] = rn

它产生输出:

acquired
random no: 10
Value: [10], : Thread-1
released

为什么在主线程中更改列表会导致另一个线程中的列表发生变化,即使它已被锁定?我能做些什么来防止它?谢谢。

最佳答案

因为锁只有在你改变列表的所有地方都使用时才会起作用,所以如果你只在一个地方调用它,它就不是一个无处不在的魔法。

为了保护列表,您需要在两个线程上添加锁上下文:

lock = threading.Lock()

def createstuff(data):
t= threading.Thread(target=func, args=(data,))
t.start()

def func(val):
with lock:
print 'thread: acquired'
time.sleep(2)
print ('Value: %s, : %s'%(val, threading.currentThread().getName()))
print 'thread released'

ags_list = ['x']


createstuff(ags_list)

with lock:
print 'thread: acquired'
rn =random.randint(5,50)
print 'random no:', rn
ags_list[0] = rn
print 'thread: released'

您可以创建一个线程安全列表,例如:

class ThreadSafeList(list):
def __init__(self, *args):
super(ThreadSafeList, self).__init__(*args)
self.lock = threading.Lock()
def __setitem__(self, idx, value):
with self.lock:
print 'list acquired'
super(ThreadSafeList, self)[idx] = value
print 'list released'

然后使用它:

def createstuff(data):
t= threading.Thread(target=func, args=(data,))
t.start()

def func(val):
time.sleep(2)
print ('Value: %s, : %s'%(val, threading.currentThread().getName()))

args_list = ThreadSafeList(['x'])
createstuff(args_list)
rn =random.randint(5,50)
print 'random no:', rn
args_list[0] = rn

当然这只是一个例子,还有待完善和完善。在这里,我更愿意关注这一点。

虽然你不需要线程中的锁,因为从列表中访问一个值是(afaict)一个原子只读操作,所以列表的变化只能发生在值被访问之前或之后列表,而不是因为它正在访问值。所以最后你的例子中不应该有任何种族问题。

如果您正在修改列表的值,或者对数据进行非原子访问,那么锁可能会有用。

注意:如果您认为它可以以任何其他方式工作:互斥锁机制(通过 Lock 实现)不保护数据,它防止两个执行线程同时执行。如果您在线程 A 中断言锁定,在线程 B 中断言相同的锁之前,线程 B 将等待 线程 A 解除锁定直到完成它的工作。

关于python - python 中的线程锁无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23783656/

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