怎样在Python中调试pytest死锁和超时问题

轻雪同学_5097

轻雪同学_5097

2026-10-17

535人浏览

原创

用 py-spy record -p pid -o flame.svg 直接抓取进程调用栈,重点关注停在 lock.acquire、queue.get、join 等阻塞调用的线程,可精准定位死锁点。

怎样在python中调试pytest死锁和超时问题

pytest运行卡住不动,怎么快速定位死锁点

直接看进程状态比猜更可靠。先用 ps aux | grep pytest 找到主进程 PID,再执行 kill -3 PID(Linux/macOS)或 py-spy record -p PID -o flame.svg(推荐),它会输出当前所有线程的完整调用栈。重点关注处于 Waiting for condition、acquire、join 或长时间停在 threading.Lock.acquire / queue.get 的线程。

常见诱因包括:

  • 测试函数里手动调用了 threading.Thread.join() 但没设 timeout,且被测线程内部又等了另一个未释放的锁
  • 使用了 concurrent.futures.ThreadPoolExecutor 但没调用 shutdown(wait=True),导致 pytest 主线程在 exit 阶段阻塞在 executor 的 weakref 回收逻辑中(Python 3.9+ 更明显)
  • pytest-xdist 下多个 worker 同时访问同一本地文件(如 SQLite 文件、临时目录),而没加文件锁或隔离路径

给单个测试加超时,但不干扰 fixture 生命周期

用 pytest-timeout 插件最稳妥,它在信号层介入,不依赖测试代码配合。安装后加配置:

addopts = --timeout=30 --timeout-method=signal

注意 --timeout-method=signal(默认)比 thread 更可靠:后者靠另起监控线程抛异常,若被测代码已禁用线程(如 threading.settrace)或卡死在 C 扩展里就无效;前者用 SIGALRM 强制中断,但 Windows 不支持。

若必须用装饰器方式(如只对特定测试),避免用 @pytest.mark.timeout(需额外插件),改用标准库:

import signal<br>def timeout_handler(signum, frame):<br>    raise TimeoutError("test hung")<br><br>def test_something():<br>    signal.signal(signal.SIGALRM, timeout_handler)<br>    signal.alarm(5)  # 5秒后触发<br>    try:<br>        # your code here<br>    finally:<br>        signal.alarm(0)  # 清除定时器

关键点:必须在 try/finally 中调用 signal.alarm(0),否则超时后信号持续挂起,后续测试全崩。

Claw Code Suite (Python-Only Edition)
Claw Code Suite (Python-Only Edition)

仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...

下载

fixture 中启动后台线程,为什么 pytest 退出时卡住

根本原因是 pytest 默认等待所有非守护线程结束才退出。如果你在 setup 或 fixture 中起了 threading.Thread(target=...),又没设 daemon=True,pytest 就会卡在 thread.join()。

正确做法分场景:

  • 纯测试辅助线程(如 mock server):显式设 daemon=True,并确保它不持有关键资源(如数据库连接、文件句柄)
  • 需主动控制生命周期的线程:用 fixture 的 yield + thread.stop() 模式,但注意 Python 没原生 stop(),得自己实现退出标志位(如 threading.Event)
  • 涉及 asyncio 的:别混用 threading 和 asyncio.run(),优先用 asyncio.create_task() + asyncio.wait_for(),pytest-asyncio 插件能自动处理事件循环关闭

一个典型错误是写 thread = threading.Thread(target=run_server); thread.start(); yield; thread.join() —— 若 run_server 内部阻塞在 socket.accept() 且没响应中断,join() 就永远等下去。

复现不稳定死锁,怎么固定测试顺序和并发行为

随机性是调试死锁的最大敌人。先用 --randomly-seed=12345(需 pytest-randomly)固定执行顺序,再用 -n0 关掉 xdist 并发,排除多 worker 干扰。

进一步控制环境:

  • 强制单线程:启动时加 PYTHONPATH=. 和 export OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1(防科学计算库偷偷开线程)
  • 禁用缓存:加 --cache-clear,避免旧的 .pytest_cache 里残留锁状态
  • 检查日志:在 conftest.py 里加全局 logging.basicConfig(level=logging.DEBUG),重点观察 threading、queue、concurrent.futures 相关模块的 debug 日志

真正难搞的是那些依赖系统调度时序的锁竞争——这时候得上 py-spy 抓多个时间点的栈快照对比,看哪个线程总在同一个锁上反复等待。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1751

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4504

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1729

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

26477

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3207

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3227

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1183

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2503

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习