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

Python线程中两种join()调用方式的差异是什么?

关于Python threading中join()方法位置的差异解析

问题描述

我想用threading包计算数字的平方,写了如下代码,但对join()方法的放置位置感到困惑——虽然两种写法输出结果相同,但猜测存在差异,想了解具体区别:

import threading
def my_squr(num):   #if this function take long time to run
    print(num*num)
    return num*num

if __name__ == "__main__":

    l1 = [1,3,5,7,11,13,15,17]
    for i, item in enumerate(l1):
        if i % 3 == 0:
            t1 = threading.Thread(target=my_squr, args=(item,))
            t1.start()
            t1.join()
        elif i % 3 == 1:
            t2 = threading.Thread(target=my_squr, args=(item,))
            t2.start()
            t2.join()
        else:
            t3 = threading.Thread(target=my_squr, args=(item,))
            t3.start()
            t3.join()

    # t1.join()
    # t2.join()
    # t3.join()

    print("Done")

两种join()写法的核心区别

1. 循环内调用join()(当前代码的写法)

这种写法本质是串行执行所有线程:

  • 每启动一个线程后立刻调用t.join(),会强制主线程暂停,直到这个子线程完全执行完毕,才会进入下一次循环处理下一个元素
  • 相当于放弃了多线程的并发优势,和直接在主线程里逐个调用my_squr(item)没有区别
  • 如果my_squr是耗时任务(比如加time.sleep(1)),总耗时等于所有任务执行时间的总和(比如8个任务各耗时1秒,总耗时8秒)

2. 循环外调用join()(注释写法需修正后才正确)

原注释中的写法有bug:t1/t2/t3会被循环多次赋值,最后join()的只是最后一次创建的线程,前面的线程未被主线程等待。正确的做法是把所有线程对象存入列表再统一join():

import threading
def my_squr(num):
    print(num*num)
    return num*num

if __name__ == "__main__":
    l1 = [1,3,5,7,11,13,15,17]
    threads = []
    for item in l1:
        t = threading.Thread(target=my_squr, args=(item,))
        threads.append(t)
        t.start()
    
    # 统一等待所有线程完成
    for t in threads:
        t.join()
    
    print("Done")

这种写法的核心是并发执行所有线程:

  • 先一次性启动所有子线程,让它们同时运行(IO密集型任务能明显提升效率,CPU密集型受Python GIL限制效果有限,但逻辑上是并发)
  • 主线程最后等待所有子线程执行完毕后,才会打印Done
  • 如果my_squr是耗时任务,总耗时等于单个任务的最长执行时间(比如8个任务各耗时1秒,总耗时约1秒)

为什么两种写法结果看起来相同?

因为你的my_squr是极快的计算任务,线程启动和执行的时间可以忽略不计,串行和并发的执行效果在输出上几乎没有差别。如果给my_squr加上耗时操作(比如time.sleep(1)),就能立刻看到两种写法的耗时差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:40:26