threading.Thread不执行目标函数的主因是target传了函数调用(如my_func())而非函数引用(my_func),且主线程未调用join()导致子线程被终止;CPU密集型任务无加速源于GIL限制,应改用multiprocessing或numpy等绕过GIL的方案。
threading.Thread 启动后不执行目标函数?常见现象是调用了 t.start(),但 target 函数毫无反应。根本原因通常是:把函数调用写成了函数引用 —— 例如传了 target=my_func()(带括号),实际应传 target=my_func(不带括号)。
另一个高频坑是主线程结束太快,子线程被强制终止(尤其在脚本末尾没加 t.join())。Python 的 threading 模块不会自动等待子线程完成。
实操建议:
target 参数是否为函数名本身,而非调用表达式Thread 实例,若需确保其执行完毕,必须显式调用 .join()
target 函数中直接修改全局变量而不加锁 —— 即使看起来“只是读”,也可能因字节码交错引发意外queue.Queue 在多线程间安全传数据,但程序卡死?典型表现是生产者调用 q.put(item) 后阻塞,或消费者调用 q.get() 后永远等不到数据。这不是队列“坏了”,而是没理解 queue.Queue 的阻塞机制和配套方法语义。
关键点:
q.get() 默认阻塞,直到有数据;若确定队列非空,可加 timeout=1 避免无限等待q.task_done() 必须与 q.join() 配对 —— 每次 get() 后处理完任务,就得调一次 task_done(),否则 join() 永远不会返回q.empty() 和 q.qsize() 在多线程下不可靠,仅作粗略参考,不能用于条件判断逻辑threading 几乎不提速?这是 Python 的 GIL(全局解释器锁)导致的硬限制:同一时刻只有一个线程执行 Python 字节码。所以纯计算任务(如循环累加、正则匹配大量文本、数值计算)无法通过多线程并行利用多核。
应对策略取决于场景:
threading 依然有效 —— I/O 时 GIL 会释放,其他线程可运行multiprocessing 模块,每个进程有独立解释器和 GILnumpy 或 scipy 加速 —— 它们的底层 C 实现绕过 GIL,此时多线程也能受益print 输出乱序甚至缺失?不是 bug,是标准输出(sys.stdout)默认行缓冲 + 线程竞争的结果。多个线程同时调 print(),可能把不同线程的字符串碎片混在一起,或因缓冲未刷新而丢失。
临时解决办法(仅限调试):
print() 加 flush=True 参数,如 print("msg", flush=True)
logging 模块替代 —— 它线程安全,且支持格式化和输出定向queue.Queue,由单个线程统一输出GIL 不保证 print 原子性,这点容易被忽略 —— 即使只 print 一个变量,背后也涉及对象转换、编码、写缓冲多个步骤,中间可能被切换。