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

2024-04-25 20:36:33 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

然后按预期工作打印随机数。你知道吗


Tags: importlocktimedefcountwithrandomglobal
1条回答
网友
1楼 · 发布于 2024-04-25 20:36:33

大多数情况下,当线程转到sleep时,CPU会将上下文切换到其他线程。
因此,在您的代码中,在两个线程都已完成第一个with lock块之后(即在两个线程都更改count值之后),两个线程都到达第二个with lock块。
因此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命令)

相关问题 更多 >