Existe-t-il un équivalent à CTRL + C dans IPython Notebook dans Firefox pour casser les cellules en cours d'exécution?

100

J'ai commencé à utiliser le notebook IPython et je l'apprécie. Parfois, j'écris du code bogué qui nécessite énormément de mémoire ou qui a une boucle infinie. Je trouve l'option "interrompre le noyau" lente ou peu fiable, et parfois je dois redémarrer le noyau, perdant tout en mémoire.

J'écris aussi parfois des scripts qui font que OS X manque de mémoire et je dois faire un redémarrage dur. Je ne suis pas sûr à 100%, mais quand j'ai écrit des bogues comme celui-ci avant et exécuté Python dans le terminal, je peux généralement CTRL+ Cmes scripts.

J'utilise la distribution Anaconda du notebook IPython avec Firefox sur Mac OS X.

wwwilliam
la source
1
Je n'ai jamais réussi à interrompre une boucle infinie via le raccourci cntrl + mi ou le menu déroulant noyau> interruption en 0.13 (par défaut pour anaconda sur MacOSX). Le problème semble être résolu dans la version 1.0.
KLDavenport

Réponses:

55

Je peux me tromper, mais je suis presque sûr que le bouton "interrompre le noyau" envoie simplement un signal SIGINT au code que vous utilisez actuellement (cette idée est soutenue par le commentaire de Fernando ici ), ce qui est la même chose que frapper CTRL + C ferait l'affaire. Certains processus au sein de python gèrent les SIGINT plus brusquement que d'autres.

Si vous avez désespérément besoin d'arrêter quelque chose qui s'exécute dans iPython Notebook et que vous avez démarré iPython Notebook à partir d'un terminal, vous pouvez appuyer deux fois sur CTRL + C dans ce terminal pour interrompre l'ensemble du serveur iPython Notebook. Cela arrêtera complètement iPython Notebook, ce qui signifie qu'il ne sera pas possible de redémarrer ou d'enregistrer votre travail, donc ce n'est évidemment pas une excellente solution (vous devez appuyer deux fois sur CTRL + C car c'est une fonction de sécurité pour que les gens ne le fassent pas) faites-le par accident). En cas d'urgence, cependant, il tue généralement le processus plus rapidement que le bouton "interrompre le noyau".

seaotternerd
la source
13
Vous pouvez également redémarrer ou arrêter le noyau incriminé - moins radical que de tuer le serveur ipython. Cela peut être fait à partir du Kernelmenu déroulant ou de la page du serveur de notebook (le Shutdownbouton à droite du nom du notebook incriminé).
drevicko
1
Malheureusement, il semble que le navigateur puisse devenir si insensible qu'il est difficile d'atteindre la page du serveur.
K.-Michael Aye
Existe-t-il un moyen d'interrompre un processus jupyter-console? II / control-c ne fonctionne pas. Et il n'y a pas d'autre raccourci pour redémarrer le noyau.
alpha_989
76

Vous pouvez appuyer sur I deux fois pour interrompre le noyau.

Cela ne fonctionne que si vous êtes en mode Commande. S'il n'est pas déjà activé, appuyez sur Escpour l'activer.

la mignonne
la source
S'agit-il d'une plage de versions spécifique d'IPython ou d'un système d'exploitation spécifique?
Greg
6

Voici des raccourcis pour le bloc-notes IPython.

Ctrl-m iinterrompt le noyau. (c'est-à-dire la seule lettre i après Ctrl-m)

Selon cette réponse, Ideux fois fonctionne aussi.

Skuli
la source
5

Pour ajouter à ce qui précède: Si l'interruption ne fonctionne pas, vous pouvez redémarrer le noyau.

Accédez à la liste déroulante du noyau >> redémarrer >> redémarrer et effacer la sortie. Cela fait généralement l'affaire. Si cela ne fonctionne toujours pas, tuez le noyau dans le terminal (ou le gestionnaire de tâches) puis redémarrez.

L'interruption ne fonctionne pas bien pour tous les processus. J'ai surtout ce problème en utilisant le noyau R.

tomp
la source
Cette astuce l'a fait pour moi: Jupyter Notebook totalement insensible en raison du regroupement kmeans multi-core de 2 milliards d'entrées (aurait dû le savoir auparavant)
Alex
3

METTRE À JOUR : J'ai transformé ma solution en un script python autonome.

Cette solution m'a sauvé plus d'une fois. J'espère que d'autres le trouveront utile. Ce script python trouvera n'importe quel noyau jupyter utilisant plus que le cpu_thresholdprocesseur et invite l'utilisateur à envoyer un SIGINTau noyau (KeyboardInterrupt). Il continuera à envoyer SIGINTjusqu'à ce que l'utilisation du processeur par le noyau soit inférieure cpu_threshold. S'il y a plusieurs noyaux qui se comportent mal, cela demandera à l'utilisateur d'interrompre chacun d'eux (triés par l'utilisation du processeur la plus élevée au plus bas). Un grand merci à gcbeltramini pour avoir écrit du code pour trouver le nom d'un noyau jupyter en utilisant l'API jupyter. Ce script a été testé sur MACOS avec python3 et nécessite jupyter notebook, requests, json et psutil.

Mettez le script dans votre répertoire personnel et son utilisation ressemble à ceci:

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

Code de script ci-dessous:

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
la source