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

Python多线程中target传函数名与带括号的差异及原因咨询

Python多线程中target传参差异的原因分析

问题场景

在学习Python多线程的**竞态条件(race condition)和锁(lock)**概念时,遇到一个特殊现象:

测试代码如下:

from threading import Thread
import time

value = 0
def increase():
    global value
    local = value
    local += 1
    time.sleep(0.1)
    value = local

print('start value', value)

#create threads
thread1 = Thread(target=increase)
thread2 = Thread(target=increase)

#start threads
thread1.start()
thread2.start()

#join threads
thread1.join()
thread2.join()

print('end value', value)

print('end main')

两种传参方式的执行结果

  • target传入函数名increase(不带括号)
    执行结果:
start value 0
end value 1
end main

这是竞态条件下的正常结果。

  • target传入increase()(带括号)
    执行结果:
start value 0
end value 2
end main

未使用锁却得到了类似加锁的结果,这一现象的原因是什么?

原因解析

核心问题在于Thread类的target参数的作用逻辑:

  1. 当传入increase(不带括号)时,你传递的是函数对象,线程启动后会自动调用这个函数。此时两个线程并发执行increase,触发竞态条件:两个线程都先读取到value=0,各自加1后休眠,最后先后把value设为1,最终结果为1。
  2. 当传入increase()(带括号)时,你传递的不是函数,而是立即在主线程中执行increase()后的返回值(此处为None)。线程启动后,由于target是None,不会执行任何有效逻辑。

最终value=2的原因是:创建线程对象时,你已经在主线程里顺序执行了两次increase():

thread1 = Thread(target=increase())  # 主线程执行一次increase,value变为1
thread2 = Thread(target=increase())  # 主线程再执行一次increase,value变为2

后续启动的两个线程并未参与value的修改,所以最终结果是主线程两次调用后的2,和多线程并发毫无关系。

简单来说,带括号的写法根本没用到多线程并发,只是在主线程里顺序执行了两次函数,自然不会出现竞态条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 10:06:44