带锁的python线程给出相同的值

时间:2014-07-07 07:20:29

标签: 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))
    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

然后按预期打印随机数。

1 个答案:

答案 0 :(得分:0)

大多数情况下,当线程转到sleep时,CPU会将上下文切换到其他线程 因此,在您的代码中,两个线程在两个线程都已完成第一个with lock块之后(即在它们都更改with lock值之后)到达第二个count块。 因此count不再更改,并且当它们到达第二个锁定区并打印count值时包含特定值。 (在incrementdecrement完成第一个with lock块之后。

如果您想看到差异,请将其更改为:

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命令)