Esiste un equivalente di CTRL + C in IPython Notebook in Firefox per rompere le celle in esecuzione?


100

Ho iniziato a utilizzare IPython Notebook e mi sto divertendo. A volte, scrivo codice difettoso che richiede enormi requisiti di memoria o ha un ciclo infinito. Trovo l'opzione "interrompi kernel" lenta o inaffidabile, ea volte devo riavviare il kernel, perdendo tutto in memoria.

A volte scrivo anche script che causano l'esaurimento della memoria di OS X e devo eseguire un riavvio forzato. Non ne sono sicuro al 100%, ma quando ho già scritto bug come questo e ho eseguito Python nel terminale, di solito posso CTRL+ i Cmiei script.

Sto usando la distribuzione Anaconda del notebook IPython con Firefox su Mac OS X.


1
Non sono mai riuscito a interrompere un ciclo infinito tramite la scorciatoia cntrl + mi o il menu a discesa kernel> interrupt in 0.13 (predefinito per anaconda su MacOSX). Il problema sembra essere stato risolto nella 1.0.
KLDavenport

Risposte:


55

Potrei sbagliarmi, ma sono abbastanza sicuro che il pulsante "interrompi kernel" invia semplicemente un segnale SIGINT al codice che stai attualmente eseguendo (questa idea è supportata dal commento di Fernando qui ), che è la stessa cosa che colpire CTRL + C andrebbe bene. Alcuni processi all'interno di python gestiscono i SIGINT più bruscamente di altri.

Se hai un disperato bisogno di fermare qualcosa che è in esecuzione in iPython Notebook e hai avviato iPython Notebook da un terminale, puoi premere CTRL + C due volte in quel terminale per interrompere l'intero server iPython Notebook. Ciò interromperà completamente iPython Notebook, il che significa che non sarà possibile riavviare o salvare il tuo lavoro, quindi questa ovviamente non è un'ottima soluzione (devi premere CTRL + C due volte perché è una funzione di sicurezza in modo che le persone non lo facciano fallo per sbaglio). In caso di emergenza, tuttavia, generalmente interrompe il processo più rapidamente del pulsante "interrompi kernel".


13
In alternativa, puoi riavviare o fermare il kernel incriminato, meno drastico che uccidere il server ipython. Questa operazione può essere eseguita dal Kernelmenu a discesa o dalla pagina del server del notebook (il Shutdownpulsante a destra del nome del notebook incriminato).
drevicko

1
Purtroppo sembra che il browser possa diventare così insensibile che è difficile raggiungere la pagina del server.
K.-Michael Aye

C'è un modo per interrompere un processo jupyter-console? II / control-c non funziona. E non ci sono altre scorciatoie per riavviare il kernel.
alpha_989

75

Puoi premere I due volte per interrompere il kernel.

Funziona solo se sei in modalità di comando. Se non è già abilitato, premere Escper abilitarlo.


È per un intervallo di versioni specifico di IPython o per un sistema operativo specifico?
Greg

6

Qui scorciatoie per il notebook IPython.

Ctrl-m iinterrompe il kernel. (cioè l'unica lettera i dopoCtrl-m )

Secondo questa risposta, anche Idue volte funziona.


5

Per aggiungere a quanto sopra: Se l'interrupt non funziona, puoi riavviare il kernel.

Vai al menu a discesa del kernel >> riavvia >> riavvia e cancella l'output. Questo di solito fa il trucco. Se ancora non funziona, elimina il kernel nel terminale (o nel task manager) e poi riavvia.

L'interrupt non funziona bene per tutti i processi. Ho particolarmente questo problema usando il kernel R.


Questo trucco ha funzionato per me: Notebook Jupyter totalmente non responsivo a causa del clustering kmeans multi-core di 2 miliardi di voci (avrei dovuto saperlo prima)
Alex

3

AGGIORNAMENTO : trasformato la mia soluzione in uno script Python autonomo.

Questa soluzione mi ha salvato più di una volta. Si spera che altri lo trovino utile. Questo script python troverà qualsiasi kernel jupyter che utilizza più della cpu_thresholdCPU e richiede all'utente di inviare un messaggio SIGINTal kernel (KeyboardInterrupt). Continuerà a inviare SIGINTfino a quando l'utilizzo della CPU del kernel non sarà inferiore cpu_threshold. Se ci sono più kernel che si comportano in modo anomalo, verrà chiesto all'utente di interromperli (ordinati dal più alto utilizzo della CPU al più basso). Un grande ringraziamento va a gcbeltramini per aver scritto il codice per trovare il nome di un kernel jupyter usando l'api jupyter. Questo script è stato testato su MACOS con python3 e richiede jupyter notebook, richieste, json e psutil.

Metti lo script nella tua home directory e quindi l'utilizzo sarà simile a:

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

Codice dello script di seguito:

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()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.