Есть ли эквивалент CTRL + C в IPython Notebook в Firefox для разрушения работающих ячеек?

103

Я начал использовать IPython Notebook, и мне это нравится. Иногда я пишу код с ошибками, который требует больших объемов памяти или имеет бесконечный цикл. Я считаю, что опция «прерывание ядра» работает медленно или ненадежно, и иногда мне приходится перезапускать ядро, теряя все в памяти.

Я также иногда пишу сценарии, из-за которых OS X не хватает памяти, и мне приходится выполнять жесткую перезагрузку. Я не уверен на 100%, но когда я раньше писал подобные ошибки и запускал Python в терминале, я обычно могу CTRL+ Cсвои скрипты.

Я использую дистрибутив Anaconda для ноутбука IPython с Firefox на Mac OS X.

wwwilliam
источник
1
Мне никогда не удавалось прерывать бесконечный цикл с помощью сочетания клавиш cntrl + mi или выпадающего меню kernel> interrupt в 0.13 (по умолчанию для anaconda в MacOSX). Проблема вроде бы исправлена ​​в 1.0.
KLDavenport

Ответы:

57

Я могу ошибаться, но я почти уверен, что кнопка «прерывание ядра» просто отправляет сигнал SIGINT коду, который вы сейчас выполняете (эта идея поддерживается комментарием Фернандо здесь ), что то же самое, что и нажатие CTRL + C подойдет. Некоторые процессы в Python обрабатывают SIGINT более резко, чем другие.

Если вам отчаянно нужно остановить что-то, что работает в iPython Notebook, и вы запустили iPython Notebook с терминала, вы можете дважды нажать CTRL + C в этом терминале, чтобы прервать работу всего сервера iPython Notebook. Это полностью остановит iPython Notebook, что означает, что будет невозможно перезапустить или сохранить вашу работу, поэтому это, очевидно, не лучшее решение (вам нужно дважды нажать CTRL + C, потому что это функция безопасности, чтобы люди не сделать это случайно). Однако в экстренных случаях она обычно завершает процесс быстрее, чем кнопка «прерывание ядра».

Seaotternerd
источник
13
В качестве альтернативы вы можете перезапустить или остановить неисправное ядро ​​- менее радикально, чем убить сервер ipython. Это можно сделать из Kernelраскрывающегося списка или со страницы сервера ноутбука ( Shutdownкнопка справа от имени записной книжки).
drevicko
1
К сожалению, кажется, что браузер может перестать отвечать на запросы, что затрудняет доступ к странице сервера.
К.-Майкл Айе
Есть ли способ прервать процесс jupyter-console? II / control-c не работает. И другого ярлыка для перезагрузки ядра нет.
alpha_989
79

Вы можете Iдважды нажать, чтобы прервать работу ядра.

Это работает, только если вы находитесь в командном режиме. Если он еще не включен, нажмите, Escчтобы включить его.

милашка
источник
Это для определенного диапазона версий IPython или конкретной ОС?
Грег
Ты только что сэкономил мне 20 минут, спасибо, незнакомец
sapo_cosmico
6

Вот ярлыки для IPython Notebook.

Ctrl-m iпрерывает ядро. (то есть единственная буква i после Ctrl-m)

Согласно этому ответу, Iдважды работает.

Скули
источник
5

Чтобы добавить к вышесказанному: Если прерывание не работает, вы можете перезапустить ядро.

Перейдите в раскрывающееся меню ядра >> перезапуск >> перезапуск и очистите вывод. Обычно это помогает. Если это все еще не работает, убейте ядро ​​в терминале (или диспетчере задач), а затем перезапустите.

Прерывание работает не для всех процессов. У меня особенно эта проблема возникает при использовании ядра R.

гудок
источник
Этот трюк сделал это для меня: полностью зависший Jupyter Notebook из-за многоядерной кластеризации kmeans из 2 миллиардов записей (должно было быть известно раньше)
Alex
4

ОБНОВЛЕНИЕ : превратили мое решение в автономный скрипт Python.

Это решение меня не раз спасало. Надеюсь, другие сочтут это полезным. Этот скрипт python найдет любое ядро ​​jupyter, использующее не только cpu_thresholdпроцессор, и предложит пользователю отправить SIGINTядру (KeyboardInterrupt). Он будет продолжать отправку, SIGINTпока использование процессора ядром не станет ниже cpu_threshold. Если имеется несколько некорректно работающих ядер, пользователю будет предложено прервать каждое из них (упорядоченное по самой низкой загрузке ЦП). Большое спасибо gcbeltramini за написание кода для поиска имени ядра jupyter с помощью jupyter api. Этот скрипт был протестирован на MACOS с python3 и требует jupyter notebook, запросов, 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()
Mbecker
источник