Чи є еквівалент CTRL + C у ноутбуці IPython у Firefox, щоб зламати клітини, що працюють?


100

Я почав використовувати ноутбук IPython і мені це подобається. Іноді я пишу баггі-код, який займає величезні потреби в пам'яті або має нескінченний цикл. Я вважаю, що параметр "ядро переривання" є млявим або ненадійним, і іноді мені доводиться перезавантажувати ядро, втрачаючи все в пам'яті.

Я також іноді пишу сценарії, через які в OS X закінчується пам’ять, і мені доводиться жорстко перезавантажуватись. Я не впевнений на 100%, але коли я писав такі помилки раніше і запускав Python в терміналі, я зазвичай можу CTRL+ Cсвої сценарії.

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


1
Я ніколи не мав успіху в перериванні нескінченного циклу за допомогою ярлика cntrl + mi або ядра> переривання в 0,13 (за замовчуванням для анаконда на MacOSX). Здається, проблема виправлена ​​в 1.0.
KLDavenport

Відповіді:


55

Я можу помилитися, але я впевнений, що кнопка "ядро переривання" просто надсилає сигнал SIGINT до коду, який ви зараз працюєте (ця ідея підтримується коментарем Фернандо тут ), що це те саме, що потрапляє CTRL + C зробив би. Деякі процеси в python обробляють SIGINT крутіше, ніж інші.

Якщо вам відчайдушно потрібно зупинити щось, що працює в iPython Notebook, і ви запустили iPython Notebook з терміналу, ви можете натиснути CTRL + C двічі в цьому терміналі, щоб перервати весь сервер ноутбуків iPython. Це повністю зупинить ноутбук iPython, а це означає, що не можна буде перезапустити або зберегти свою роботу, тому це, очевидно, не чудове рішення (вам потрібно натиснути CTRL + C двічі, оскільки це функція безпеки, щоб люди не стали зробіть це випадково). Однак у випадку надзвичайних ситуацій, як правило, процес вбиває процес швидше, ніж кнопка "ядро переривання".


13
Крім того, ви можете перезапустити або зупинити оскорбляюче ядро ​​- менш кардинально, ніж вбити сервер ipython. Це можна зробити зі Kernelспадного меню або зі сторінки сервера ноутбуків ( Shutdownкнопка праворуч від імені блокнота, що порушує право).
drevicko

1
На жаль, здається, що браузер може настільки не відповідати, що важко дістатися до сторінки сервера.
К.-Майкл Айе

Чи є спосіб перервати процес в jupyter-console? II / control-c не працює. І немає іншого ярлика для перезавантаження ядра.
alpha_989

75

Ви можете натиснути Iдвічі, щоб перервати ядро.

Це працює лише в режимі Command. Якщо це ще не ввімкнено, натисніть, Escщоб увімкнути його.


Це для певного діапазону версій IPython або певної ОС?
Грег

6

Ось ярлики для ноутбука IPython.

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

Відповідно до цієї відповіді, також Iпрацює двічі.


5

Щоб додати до сказаного: Якщо переривання не працює, ви можете перезапустити ядро.

Перейдіть до випадаючого ядра >> перезавантаження >> перезавантаження та очищення результатів. Зазвичай це робить трюк. Якщо це все ще не працює, вбийте ядро ​​в терміналі (або диспетчері завдань), а потім перезапустіть.

Переривання не працює добре для всіх процесів. Особливо у мене є ця проблема із використанням ядра R.


Цей трюк зробив це для мене: абсолютно невідповідальний ноутбук Юпітера через багатоядерні кмени, що складаються з 2 мільярдів записів (повинні були знати раніше)
Алекс

3

ОНОВЛЕННЯ : Перетворив моє рішення на окремий сценарій пітона.

Це рішення рятувало мене не раз. Сподіваємось, інші вважають це корисним. Цей скрипт python знайде будь-яке ядро ​​юпітера, що використовує більше cpu_thresholdCPU, і спонукає користувача надіслати SIGINTядро (KeyboardInterrupt). Надсилатиметься, SIGINTпоки використання процесорного ядра не знизиться cpu_threshold. Якщо є декілька ядер, що не ведуть себе в службу, він запропонує користувачеві перервати кожне з них (впорядковано від найвищого використання процесора до найнижчого). Велика подяка gcbeltramini за написання коду, щоб знайти ім'я ядра джупітера за допомогою jupyter api. Цей сценарій був протестований на MACOS з python3 і вимагає ноутбука юпітера, запитів, 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()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.