在Firefox中的IPython Notebook中是否有相当于CTRL + C来破坏正在运行的单元格?

时间:2013-07-10 01:48:42

标签: python ipython jupyter-notebook

我已经开始使用IPython笔记本了,我很享受。有时,我会编写需要大量内存或无限循环的错误代码。我发现“中断内核”选项缓慢或不可靠,有时我必须重新启动内核,丢失内存中的所有内容。

我有时也会写脚本导致OS X耗尽内存,我必须重新启动硬盘。我不是百分百肯定,但是当我之前写过这样的错误并在终端中运行Python时,我通常可以 CTRL + C 我的脚本。

我在Mac OS X上使用Anaconda分发的IPython笔记本和Firefox。

6 个答案:

答案 0 :(得分:58)

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

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

答案 1 :(得分:48)

我可能错了,但我很确定“中断内核”按钮只是向你当前正在运行的代码发送一个SIGINT信号(这个想法得到费尔南多的评论here支持),这与击中CTRL + C会做同样的事情。 python中的某些进程比其他进程更突然地处理SIGINT。

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

答案 2 :(得分:4)

Here是IPython Notebook的快捷方式。

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

根据this回答,I两次也有效。

答案 3 :(得分:3)

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

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

中断对所有进程都不起作用。我特别使用R内核来解决这个问题。

答案 4 :(得分:1)

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

此解决方案为我节省了不止一次。希望其他人觉得它有用。此python脚本将使用超过cpu_threshold的CPU查找任何jupyter内核,并提示用户向内核发送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()

答案 5 :(得分:-1)

更快的替代方法是简单地复制localhost地址,cmd上的Ctrl C以停止服务器,重新启动服务器然后将地址粘贴到新选项卡。