web-dev-qa-db-fra.com

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

J'ai commencé à utiliser le bloc-notes IPython et je l'apprécie. Parfois, j'écris un code buggy qui prend énormément de mémoire ou qui a une boucle infinie. Je trouve l'option "interruption kernel" lente ou peu fiable, et parfois je dois redémarrer le noyau, tout perdre en mémoire.

J'écris aussi parfois des scripts qui entraînent une insuffisance de mémoire pour OS X, et je dois effectuer un redémarrage brutal. Je ne suis pas sûr à 100%, mais quand j'ai déjà écrit des bugs comme celui-ci et que j'ai lancé Python dans le terminal, je peux généralement CTRL+C mes scripts.

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

82
wwwilliam

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. Certains processus au sein de python gèrent les SIGINT de manière plus brutale que d'autres.

Si vous avez désespérément besoin d'arrêter quelque chose qui tourne dans iPython Notebook et que vous avez démarré iPython Notebook depuis un terminal, vous pouvez appuyer deux fois sur CTRL + C dans ce terminal pour interrompre tout le serveur iPython Notebook. Cela arrêtera iPython Notebook dans son ensemble, ce qui signifie qu'il ne sera pas possible de redémarrer ou d'enregistrer votre travail. Ce n'est donc évidemment pas une bonne solution (vous devez appuyer sur CTRL + C deux fois, car c'est une fonction de sécurité faites-le par accident). En cas d'urgence, toutefois, le processus est généralement plus rapide que le bouton "Interrompre le noyau".

52
seaotternerd

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

Cela ne fonctionne que si vous êtes en mode commande. Si ce n'est déjà fait, appuyez sur Esc pour l'activer.

62
cutie

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

Allez dans 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.

4
tomp

Ici sont des raccourcis pour le Notebook IPython.

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

Selon this answer, I deux fois fonctionne également.

4
Skuli

UPDATE: a transformé ma solution en script autonome python.

Cette solution m'a sauvé plus d'une fois. J'espère que d'autres le trouveront utile. Ce script python trouvera tout noyau jupyter utilisant plus de cpu_threshold CPU et invitera l'utilisateur à envoyer un SIGINT au noyau (KeyboardInterrupt). Il continuera d'envoyer SIGINT jusqu'à ce que l'utilisation du processeur dans le noyau soit inférieure à cpu_threshold. S'il y a plusieurs noyaux qui se comportent mal, il invite l'utilisateur à les interrompre (classés par le plus faible taux d'utilisation du processeur). Un grand merci à gcbeltramini pour avoir écrit le code permettant de trouver le nom d’un noyau jupyter à l’aide de l’application jupyter api. Ce script a été testé sur MACOS avec python3 et nécessite le cahier jupyter, les requêtes, json et psutil.

Placez le script dans votre répertoire personnel, puis l'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 __== '__main__':
    interrupt_bad_notebooks()
1
mbecker