110

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

我有时也会编写导致 OS X 内存不足的脚本,我必须进行硬重启。我不是 100% 确定,但是当我之前写过这样的错误并在终端中运行 Python 时,我通常可以CTRL+C我的脚本。

我在 Mac OS X 上使用带有 Firefox 的 IPython notebook 的 Anaconda 发行版。

4

5 回答 5

87

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

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

于 2016-07-06T16:55:17.457 回答
61

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

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

于 2013-07-10T05:40:14.400 回答
7

是 IPython Notebook 的快捷方式。

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

根据这个答案,I两次也有效。

于 2016-12-12T21:55:27.487 回答
5

补充一下:如果中断不起作用,您可以重新启动内核。

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

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

于 2017-01-12T15:47:46.177 回答
4

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

这个解决方案不止一次救了我。希望其他人觉得它有用。这个 python 脚本将找到任何使用超过cpu_thresholdCPU 的 jupyter 内核,并提示用户向内核发送一个SIGINT(KeyboardInterrupt)。它将继续发送SIGINT,直到内核的 cpu 使用率低于cpu_threshold. 如果有多个行为不端的内核,它将提示用户中断每个内核(按 CPU 使用率从高到低排序)。非常感谢gcbeltramini编写代码以使用 jupyter api 查找 jupyter 内核的名称。该脚本在 MACOS 上使用 python3 进行了测试,需要 jupyter notebook、requests、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()
于 2018-10-24T20:06:52.913 回答