¿Existe un equivalente a CTRL + C en IPython Notebook en Firefox para romper las celdas que se están ejecutando?


100

Empecé a usar IPython Notebook y lo estoy disfrutando. A veces, escribo código con errores que requiere una gran cantidad de memoria o tiene un bucle infinito. Encuentro que la opción "interrumpir kernel" es lenta o poco confiable, ya veces tengo que reiniciar el kernel, perdiendo todo lo que hay en la memoria.

A veces también escribo scripts que hacen que OS X se quede sin memoria y tengo que reiniciar el sistema. No estoy 100% seguro, pero cuando escribí errores como este antes y ejecuté Python en la terminal, generalmente puedo CTRL+ Cmis scripts.

Estoy usando la distribución Anaconda del portátil IPython con Firefox en Mac OS X.


1
Nunca he tenido éxito en interrumpir un bucle infinito a través del acceso directo cntrl + mi o el menú desplegable kernel> interrupt en 0.13 (predeterminado para anaconda en MacOSX). El problema parece estar solucionado en 1.0.
KLDavenport

Respuestas:


55

Podría estar equivocado, pero estoy bastante seguro de que el botón "interrumpir kernel" simplemente envía una señal SIGINT al código que estás ejecutando actualmente (esta idea es apoyada por el comentario de Fernando aquí ), que es lo mismo que presionar CTRL + C sería suficiente. Algunos procesos dentro de Python manejan SIGINT de manera más abrupta que otros.

Si necesita desesperadamente detener algo que se está ejecutando en iPython Notebook e inició iPython Notebook desde una terminal, puede presionar CTRL + C dos veces en esa terminal para interrumpir todo el servidor de iPython Notebook. Esto detendrá iPython Notebook por completo, lo que significa que no será posible reiniciar o guardar su trabajo, por lo que obviamente esta no es una gran solución (debe presionar CTRL + C dos veces porque es una función de seguridad para que las personas no hacerlo por accidente). En caso de emergencia, sin embargo, generalmente mata el proceso más rápidamente que el botón "interrumpir kernel".


13
Alternativamente, puede reiniciar o detener el kernel ofensivo, menos drástico que matar el servidor ipython. Esto se puede hacer desde el Kernelmenú desplegable o desde la página del servidor del cuaderno (el Shutdownbotón a la derecha del nombre del cuaderno infractor).
drevicko

1
Desafortunadamente, parece que el navegador puede dejar de responder tanto que es difícil llegar a la página del servidor.
K.-Michael Aye

¿Hay alguna forma de interrumpir un proceso en jupyter-console? II / control-c no funciona. Y no hay otro atajo para reiniciar el kernel.
alpha_989

76

Puede presionar Idos veces para interrumpir el kernel.

Esto solo funciona si estás en el modo de comando. Si aún no está habilitado, presione Escpara habilitarlo.


¿Es esto para un rango de versiones específico de IPython o un sistema operativo específico?
Greg

6

A continuación, se muestran accesos directos para el cuaderno IPython.

Ctrl-m iinterrumpe el kernel. (es decir, la única letra i después Ctrl-m)

Según esta respuesta, Idos veces también funciona.


5

Para agregar a lo anterior: Si la interrupción no funciona, puede reiniciar el kernel.

Vaya al menú desplegable del kernel >> reiniciar >> reiniciar y borrar la salida. Por lo general, esto funciona. Si esto aún no funciona, elimine el kernel en la terminal (o administrador de tareas) y luego reinicie.

La interrupción no funciona bien para todos los procesos. Especialmente tengo este problema al usar el kernel R.


Este truco lo hizo por mí: Jupyter Notebook totalmente insensible debido a la agrupación de k significa de múltiples núcleos de 2 mil millones de entradas (debería haberlo sabido antes)
Alex

3

ACTUALIZACIÓN : Convertí mi solución en un script de Python independiente.

Esta solución me ha salvado más de una vez. Ojalá otros lo encuentren útil. Esta secuencia de comandos de Python encontrará cualquier kernel de jupyter que utilice más de la cpu_thresholdCPU y le pide al usuario que envíe un SIGINTal kernel (KeyboardInterrupt). Seguirá enviando SIGINThasta que el uso de la CPU del kernel sea inferior cpu_threshold. Si hay varios núcleos que se comportan mal, se le pedirá al usuario que interrumpa cada uno de ellos (ordenados por el uso de CPU más alto al más bajo). Un gran agradecimiento a gcbeltramini por escribir código para encontrar el nombre de un kernel de jupyter usando la api de jupyter. Este script se probó en MACOS con python3 y requiere un cuaderno jupyter, solicitudes, json y psutil.

Coloque el script en su directorio de inicio y luego el uso se ve así:

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

Código de secuencia de comandos a continuación:

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()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.