You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Threading与Queue时结果异常:移除time.sleep为何输出3而非1?

问题原因解析

核心:闭包的延迟绑定坑

你写的f是个闭包,它不会在定义的时候就把当时的i值存下来,而是等到实际执行的时候,才会去读当前i的真实值。而且循环里的i是同一个变量,每次迭代只是修改它的值,不是重新创建新变量。

无time.sleep时,结果为3

去掉休眠后,线程启动后会立刻执行q.put(i)。但循环创建线程的速度极快,三个线程还没来得及执行put操作,循环就已经跑完了,此时i的最终值是3。等三个线程真正执行put的时候,读取的都是已经变成3的i,所以队列里全是3,q.get()取第一个自然就是3。

保留time.sleep时,结果为1

加了休眠后,三个线程启动后会先休眠对应时长:

  • 第一个线程休眠3秒,第二个休眠2秒,第三个休眠1秒

循环跑完的速度远快于线程睡醒的速度,所以在线程们陆续睡醒之前,i已经变成了1。其中第三个线程休眠时间最短,最先醒过来执行q.put(i),这时候读取的是已经变成1的i,所以把1放进队列。q.get()会立刻取出这个第一个进入队列的1,所以打印结果就是1。

怎么解决这个问题?

如果想让每个线程都用循环当时的i值,可以给函数加个默认参数,让它在定义时就捕获当前的i:

for i in [3,2,1]:
    def f(i=i):  # 用默认参数绑定当前i的值
        time.sleep(i)
        q.put(i)
    threading.Thread(target=f).start()

这样每个f都会保存自己定义时的i值,不管后续循环怎么修改i,线程执行时用的都是当时的数值。

内容的提问来源于stack exchange,提问作者ZackR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 15:30:50