如果创建了多个锁实例,python线程中的变量锁将无法锁定?

如果创建了多个锁实例,python线程中的变量锁将无法锁定?,python,multithreading,Python,Multithreading,我不熟悉线程,有一个问题 from threading import Thread, Lock s=0 lock =Lock() ---->lock object position def sample(): global s for i in range(10000): lock.acquire() s+=1 lock.release() t1 = Thread(target=sample) t2 = Thread(target=sample) t1.s

我不熟悉线程,有一个问题

from threading import Thread, Lock
s=0
lock =Lock()  ---->lock object position
def sample():
global s
for i in range(10000):
    lock.acquire()
    s+=1
    lock.release()    
t1 = Thread(target=sample)
t2 = Thread(target=sample)
t1.start()
t2.start()
t1.join()
t2.join()
print s
由于对变量s的操作是以原子方式完成的,因此该代码给出了预期的结果20000

但是,当我更改锁创建位置时,锁没有按预期工作。我变了

 from threading import Thread, Lock
    s=0    
    def sample():
        lock =Lock()  ---> lock() added inside function
        global s
        for i in range(10000):
            lock.acquire()
            s+=1
            lock.release()    
    t1 = Thread(target=sample)
    t2 = Thread(target=sample)
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print s
随着这个变化,我得到了不一致的值。我猜这里的锁坏了。 有人能帮助我理解基于这个例子的锁工作吗? 只有当两个线程使用相同的锁对象时,锁定才会得到尊重吗


TIA在您的第一个版本中,锁是在线程启动之前创建的,并且是一个全局变量,可用于两个线程。因此,这个锁对象在线程之间共享。lock对象一次只允许一个线程获取它。当它被获取时,调用.acquire的另一个线程将阻塞,直到另一个线程调用.release。正如您所指出的,您的代码按预期工作


在第二个版本中,当您将锁创建作为局部变量移动到线程函数中时。因此,每个线程调用一个不同的示例运行,该运行创建一个唯一且不同的锁对象。每个线程总是能够在不等待的情况下获取本地锁变量,因为另一个线程总是获取另一个锁。因此,s变量实际上没有受到保护。

但是两个锁都作用于单个变量“s”,并且无论调用方是谁,变量都必须锁定@塞尔比这样想。假设s是一座房子。我们中的任何人都可以通过前门进入房子并从里面锁上。当我们离开房子时,前门没有锁。如果你把前门锁上了,我就不能进去,也不能改变房子里的家具布置——因为我们都在引用同一把锁——前门上的那把锁。但如果我突然决定使用你家的后门,而后门使用的是另一把锁,我们可以同时在家里。你的第一个版本类似于只有一扇门和一把锁的房子。你的第二个版本类似于每个人用不同的锁打开自己的门进入房子。在第二种情况下,我注意到输出只相差很小。如果我没有使用任何锁,我通常会得到15000左右的值,而不是20000。但当我使用了第二个示例中所示的错误锁时,我总是得到大约19970(只有大约30的差异)。我的意思是比较好的结果。在第二个例子中,我觉得变量并不像没有锁的情况那样100%不受保护。当没有使用正确的锁机制时,您会看到奇怪和不一致的结果,原因是每个线程都在本地缓存s的值,并将s+1的计算结果延迟回内存。语言和硬件CPU线程优化都进行了假设另一个线程没有访问相同内存的优化。如果你想了解更多细节,谷歌搜索缓存一致性。