在 Firefox 中,IPython Notebook 中是否有一个相当于 CTRL + C 的程序来中断正在运行的单元格?

我已经开始使用 IPython 笔记本,并且很喜欢它。有时,我编写的错误代码需要大量的内存需求,或者有一个无限循环。我发现“中断内核”选项迟钝或不可靠,有时我不得不重新启动内核,丢失了内存中的一切。

我有时候也会写一些脚本,这些脚本会导致 OS X 内存不足,我不得不进行一次硬重启。我不能100% 肯定,但是当我以前编写过这样的 bug 并在终端中运行 Python 时,我通常可以使用 CTRL + C脚本。

我正在 Mac OS X 上使用带有 Firefox 的 IPython 笔记本的 Anaconda 发行版。

168062 次浏览

I could be wrong, but I'm pretty sure that the "interrupt kernel" button just sends a SIGINT signal to the code that you're currently running (this idea is supported by Fernando's comment here), which is the same thing that hitting CTRL+C would do. Some processes within python handle SIGINTs more abruptly than others.

If you desperately need to stop something that is running in iPython Notebook and you started iPython Notebook from a terminal, you can hit CTRL+C twice in that terminal to interrupt the entire iPython Notebook server. This will stop iPython Notebook alltogether, which means it won't be possible to restart or save your work, so this is obviously not a great solution (you need to hit CTRL+C twice because it's a safety feature so that people don't do it by accident). In case of emergency, however, it generally kills the process more quickly than the "interrupt kernel" button.

You can press I twice to interrupt the kernel.

This only works if you're in Command mode. If not already enabled, press Esc to enable it.

Here are shortcuts for the IPython Notebook.

Ctrl-m i interrupts the kernel. (that is, the sole letter i after Ctrl-m)

According to this answer, I twice works as well.

To add to the above: If interrupt is not working, you can restart the kernel.

Go to the kernel dropdown >> restart >> restart and clear output. This usually does the trick. If this still doesn't work, kill the kernel in the terminal (or task manager) and then restart.

Interrupt doesn't work well for all processes. I especially have this problem using the R kernel.

UPDATE: Turned my solution into a stand-alone python script.

This solution has saved me more than once. Hopefully others find it useful. This python script will find any jupyter kernel using more than cpu_threshold CPU and prompts the user to send a SIGINT to the kernel (KeyboardInterrupt). It will keep sending SIGINT until the kernel's cpu usage goes below cpu_threshold. If there are multiple misbehaving kernels it will prompt the user to interrupt each of them (ordered by highest CPU usage to lowest). A big thanks goes to gcbeltramini for writing code to find the name of a jupyter kernel using the jupyter api. This script was tested on MACOS with python3 and requires jupyter notebook, requests, json and psutil.

Put the script in your home directory and then usage looks like:

python ~/interrupt_bad_kernels.py
Interrupt kernel chews cpu.ipynb; PID: 57588; CPU: 2.3%? (y/n) y

Script code below:

from os import getpid, kill
from time import sleep
import re
import signal


from notebook.notebookapp import list_running_servers
from requests import get
from requests.compat import urljoin
import ipykernel
import json
import psutil




def get_active_kernels(cpu_threshold):
"""Get a list of active jupyter kernels."""
active_kernels = []
pids = psutil.pids()
my_pid = getpid()


for pid in pids:
if pid == my_pid:
continue
try:
p = psutil.Process(pid)
cmd = p.cmdline()
for arg in cmd:
if arg.count('ipykernel'):
cpu = p.cpu_percent(interval=0.1)
if cpu > cpu_threshold:
active_kernels.append((cpu, pid, cmd))
except psutil.AccessDenied:
continue
return active_kernels




def interrupt_bad_notebooks(cpu_threshold=0.2):
"""Interrupt active jupyter kernels. Prompts the user for each kernel."""


active_kernels = sorted(get_active_kernels(cpu_threshold), reverse=True)


servers = list_running_servers()
for ss in servers:
response = get(urljoin(ss['url'].replace('localhost', '127.0.0.1'), 'api/sessions'),
params={'token': ss.get('token', '')})
for nn in json.loads(response.text):
for kernel in active_kernels:
for arg in kernel[-1]:
if arg.count(nn['kernel']['id']):
pid = kernel[1]
cpu = kernel[0]
interrupt = input(
'Interrupt kernel {}; PID: {}; CPU: {}%? (y/n) '.format(nn['notebook']['path'], pid, cpu))
if interrupt.lower() == 'y':
p = psutil.Process(pid)
while p.cpu_percent(interval=0.1) > cpu_threshold:
kill(pid, signal.SIGINT)
sleep(0.5)


if __name__ == '__main__':
interrupt_bad_notebooks()