带锁的python线程提供相同的值

带锁的python线程提供相同的值,python,multithreading,locking,Python,Multithreading,Locking,这是一个有趣的代码,虽然不是很实用,因为最好使用线程本地,但我用它来学习锁 import threading import thread import time import random count = 0 lock = threading.Lock() def increment(num): global count with lock: count += num time.sleep(random.uniform(0.2, 1.5)) wi

这是一个有趣的代码,虽然不是很实用,因为最好使用线程本地,但我用它来学习锁

import threading
import thread
import time
import random
count = 0
lock = threading.Lock()

def increment(num):
    global count
    with lock:
        count += num
    time.sleep(random.uniform(0.2, 1.5))
    with lock:
        print "t1: %f" % count

def decrement(num):
    global count
    with lock:
        count -= num
    time.sleep(random.uniform(0.2, 2.5))
    with lock:
        print "t2: %f" % count

if __name__ == "__main__":
    threads = []
    for i in range(5):
        t1 = threading.Thread(target=increment, args=(random.random(),))
        t2 = threading.Thread(target=decrement, args=(random.random(),))
        t1.start(); t2.start()
        threads.append(t1);threads.append(t2);

    # Wait for all threads to complete
    for t in threads:
        t.join()
    print "Done"
问题是它为什么打印相同的数字? 如果我在方法中使用单个锁,如:

def increment(num):
    global count
    with lock:
        count += num
        time.sleep(random.uniform(0.2, 1.5))
        print "t1: %f" % count

然后,它可以像预期的那样打印随机数。

大多数时候,当线程进入睡眠状态时,CPU会将上下文切换到其他线程。 因此,在您的代码中,两个线程都在完成第一个带锁块的线程之后到达第二个带锁块的线程,即,在两个线程都更改了计数值之后。 因此,计数不再更改,并且在达到第二个锁定块和打印计数值时包含特定值。增量和减量后,使用锁定块完成第一个

如果要查看差异,请将其更改为:

def increment(num):
    global count
    with lock:
        count += num
        time.sleep(random.uniform(0.2, 1.5))
        print "t1: %f" % count

def decrement(num):
    global count
    with lock:
        count -= num
        time.sleep(random.uniform(0.2, 2.5))
        print "t2: %f" % count

您还可以删除将证明其正确性的sleep命令

。我认为不会,因为sleep命令在时间包中,而不是线程包中。而且我只是在玩这个;对于那些想要使用此代码的人,您不需要任何sleep命令。cheers@max我不明白你想说什么。