%%time 和 %time 仅计时不中断执行,超时需靠内核心跳、容器限制或手动 signal.alarm() 等机制实现。

默认没有全局“代码运行超时”机制,Jupyter Notebook 本身不中断长时间运行的 Python 代码 —— 超时行为由内核(如 ipykernel)或底层执行环境控制,不是 Notebook 界面能直接配置的开关。
为什么 %%time 和 %time 不等于超时限制
这两个魔法命令只做计时和统计,不会主动终止执行。即使你看到 Wall time: 120.5 s,只要内核没崩、Python 进程还在跑,它就会继续下去。真正“卡死”或“无响应”,往往是内核被阻塞(比如死循环、无限等待 I/O),而非 Notebook 主动设了 timeout。
真正影响执行中断的三个层级
-
ipykernel的心跳超时:内核与 Notebook 前端通信靠心跳包,默认 30 秒无响应即标记为“dead”。可通过启动参数调整:jupyter notebook --IPKernelApp.kernel_death_interval=60(单位秒) - 内核自身资源限制:比如在 Docker 或 Kubernetes 中运行时,容器级 CPU 时间限制(
ulimit -t)或内存 OOM kill 会强制终止进程,这不是 Jupyter 控制的 - 代码层主动设限:唯一可靠的方式是自己用
signal.alarm()(Linux/macOS)或threading.Timer+sys.exit()包裹关键块,但要注意不能中断 C 扩展(如 NumPy 底层计算)
MappingKernelManager.cull_idle_timeout 是什么?它不杀正在运行的代码
这个配置项(写在 ~/.jupyter/jupyter_notebook_config.py)只针对“空闲内核”:即没有任何单元在执行、也没有客户端连接的状态下,等待多少秒后自动关闭内核。它对正在跑 for i in range(10**9) 的单元完全无效。
常见误配:c.MappingKernelManager.cull_idle_timeout = 60 → 你以为设了 60 秒超时,其实只是 60 秒没人用就关内核,和运行中卡住无关。
实际可操作的止损方案
当代码真跑飞了:
- 先按
II(命令模式下连按两次 I)中断当前内核执行(相当于发送KeyboardInterrupt),多数纯 Python 循环能响应 - 若无效,在右上角 Kernel 菜单选
Interrupt Kernel,等 5–10 秒;还不行就选Restart Kernel(会丢掉所有变量) - 长期方案:在可疑代码前加保护,例如:
import signal def timeout_handler(signum, frame): raise TimeoutError("Execution timed out") signal.signal(signal.SIGALRM, timeout_handler) signal.alarm(30) # 30秒后触发 try: # your long-running code here pass finally: signal.alarm(0) # 取消闹钟
真正难处理的是那些调用底层 C/Fortran 库(如某些 SciPy 函数、Pandas 复杂 groupby)的场景 —— 它们可能完全忽略 Python 层的 KeyboardInterrupt,此时只能靠重启内核。这也是为什么生产环境跑长任务更推荐用 papermill + CLI 方式调度,而不是依赖 Notebook UI 实时干预。


















