在Firefox的IPython Notebook中是否有等效于CTRL + C的功能来中断正在运行的单元格?


100

我已经开始使用IPython Notebook并很喜欢它。有时,我编写需要占用大量内存或存在无限循环的错误代码。我发现“中断内核”选项缓慢或不可靠,有时我不得不重新启动内核,从而丢失了内存中的所有内容。

有时我还会编写一些脚本,导致O​​S X内存不足,并且必须进行硬重启。我肯定不是100%,但如果我写这样的错误报告之前,并在终端运行的Python,我平时可以CTRL+ C我的脚本。

我在Mac OS X上使用IPython Notebook的Anaconda发行版和Firefox。


1
我从未成功通过cntrl + mi快捷方式或kernel> interrupt下拉菜单(在MacOSX上为anaconda设置)中断无限循环。该问题似乎已在1.0中修复。
KLDavenport

Answers:


55

我可能是错的,但我敢肯定的是,“中断内核”按钮,只需发送一个SIGINT信号到代码,您当前运行(这种想法是费尔南多的评论支持在这里,这是相同的东西,击打) CTRL + C可以。python中的某些进程比其他进程更突然地处理SIGINT。

如果您迫切需要停止iPython Notebook中正在运行的内容,并从终端启动iPython Notebook,则可以在该终端中按两次CTRL + C来中断整个iPython Notebook服务器。这将完全停止iPython Notebook,这意味着将无法重新启动或保存您的工作,因此,这显然不是一个很好的解决方案(您需要按CTRL + C两次,因为这是一项安全功能,因此人们无需意外地做)。但是,在紧急情况下,它通常比“中断内核”按钮更快地终止进程。


13
另外,您也可以重新启动或停止有问题的内核-比杀死ipython服务器更为轻松。可以从Kernel下拉菜单或笔记本服务器的页面(有Shutdown问题的笔记本名称右侧的按钮)完成操作。
drevicko 2013年

1
不幸的是,浏览器似乎变得反应迟钝,难以访问服务器页面。
K.-Michael Aye 2014年

有没有办法中断一个进程jupyter-console?II / control-c不起作用。而且没有其他快捷方式可以重新启动内核。
alpha_989 '18

75

您可以按I两次以中断内核。

仅当您处于命令模式时,这才有效。如果尚未启用,请按Esc启用它。


这是针对特定版本的IPython还是特定的OS?
Greg

6

是IPython Notebook的快捷方式。

Ctrl-m i中断内核。(即后面的唯一字母i Ctrl-m

根据这个答案,I两次也可以。


5

添加到上面的内容:如果中断不起作用,则可以重新启动内核。

转到内核下拉菜单>>重新启动>>重新启动并清除输出。这通常可以解决问题。如果仍然无法解决问题,请在终端(或任务管理器)中终止内核,然后重新启动。

中断不适用于所有进程。使用R内核时,我尤其遇到这个问题。


这个技巧对我有用:由于20亿个条目的多核kmeans集群(完全应该知道),Jupyter Notebook完全没有响应
亚历克斯(Alex

3

更新:将我的解决方案变成了独立的python脚本。

此解决方案为我节省了不止一次。希望其他人觉得它有用。该python脚本将查找使用不止cpu_thresholdCPU的jupyter内核,并提示用户将a发送SIGINT给内核(KeyboardInterrupt)。它将一直发送,SIGINT直到内核的cpu使用率低于为止cpu_threshold。如果存在多个行为异常的内核,它将提示用户中断每个内核(按CPU使用率从高到低的顺序排列)。非常感谢gcbeltramini编写了使用jupyter api查找jupyter内核名称的代码。该脚本已经在python3的MACOS上进行了测试,并且需要jupyter笔记本,请求,json和psutil。

将脚本放在您的主目录中,然后用法如下所示:

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

下面的脚本代码:

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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.