Apakah ada yang setara dengan CTRL + C di IPython Notebook di Firefox untuk memecah sel yang sedang berjalan?

100

Saya sudah mulai menggunakan Notebook IPython dan saya menikmatinya. Terkadang, saya menulis kode buggy yang membutuhkan kebutuhan memori yang sangat besar atau memiliki loop tak terbatas. Saya menemukan opsi "kernel interupsi" lamban atau tidak dapat diandalkan, dan terkadang saya harus memulai ulang kernel, kehilangan semua yang ada di memori.

Saya juga terkadang menulis skrip yang menyebabkan OS X kehabisan memori, dan saya harus melakukan boot ulang yang sulit. Saya tidak 100% yakin, tetapi ketika saya menulis bug seperti ini sebelumnya dan menjalankan Python di terminal, saya biasanya CTRL+ Cskrip saya.

Saya menggunakan distribusi Anaconda dari notebook IPython dengan Firefox di Mac OS X.

wwwilliam.dll
sumber
1
Saya tidak pernah berhasil menyela loop tak terbatas melalui pintasan cntrl + mi atau kernel> dropdown interrupt di 0.13 (default untuk anaconda di MacOSX). Masalahnya tampaknya diperbaiki di 1.0.
KLDavenport

Jawaban:

55

Saya bisa saja salah, tetapi saya cukup yakin bahwa tombol "interupsi kernel" hanya mengirimkan sinyal SIGINT ke kode yang sedang Anda jalankan (ide ini didukung oleh komentar Fernando di sini ), yang sama dengan yang mengenai CTRL + C sudah cukup. Beberapa proses dalam python menangani SIGINT lebih tiba-tiba daripada yang lain.

Jika Anda sangat ingin menghentikan sesuatu yang sedang berjalan di Notebook iPython dan Anda memulai Notebook iPython dari terminal, Anda dapat menekan CTRL + C dua kali di terminal itu untuk menghentikan seluruh server Notebook iPython. Ini akan menghentikan semua Notebook iPython, yang berarti tidak mungkin untuk memulai ulang atau menyimpan pekerjaan Anda, jadi ini jelas bukan solusi yang bagus (Anda perlu menekan CTRL + C dua kali karena ini adalah fitur keamanan sehingga orang tidak melakukannya secara tidak sengaja). Dalam keadaan darurat, bagaimanapun, ini biasanya mematikan proses lebih cepat daripada tombol "interrupt kernel".

seaotternerd.dll
sumber
13
Alternatifnya, Anda dapat memulai ulang atau menghentikan kernel yang bermasalah - tidak sedrastis mematikan server ipython. Ini dapat dilakukan dari Kerneldropdown atau dari halaman server buku catatan ( Shutdowntombol di sebelah kanan nama buku catatan yang melanggar).
drevicko
1
Sayangnya, tampaknya browser menjadi sangat tidak responsif, sehingga sulit untuk menjangkau halaman server.
K.-Michael Aye
Apakah ada cara untuk menghentikan proses jupyter-console? II / control-c tidak berfungsi. Dan tidak ada jalan pintas lain untuk merestart kernel.
alpha_989
76

Anda dapat menekan Idua kali untuk menghentikan kernel.

Ini hanya berfungsi jika Anda dalam mode Command. Jika belum diaktifkan, tekan Escuntuk mengaktifkannya.

manis
sumber
Apakah ini untuk rentang versi tertentu dari IPython atau OS tertentu?
Greg
6

Berikut adalah cara pintas untuk Notebook IPython.

Ctrl-m imenyela kernel. (yaitu, satu-satunya huruf i setelah Ctrl-m)

Menurut jawaban ini , Idua kali bekerja juga.

Skuli
sumber
5

Untuk menambahkan di atas: Jika interupsi tidak berfungsi, Anda dapat memulai ulang kernel.

Buka dropdown kernel >> restart >> restart dan hapus output. Ini biasanya berhasil. Jika ini masih tidak berhasil, matikan kernel di terminal (atau pengelola tugas) dan kemudian restart.

Interupsi tidak berfungsi dengan baik untuk semua proses. Saya terutama memiliki masalah ini menggunakan kernel R.

tomp
sumber
Trik ini berhasil untuk saya: Notebook Jupyter yang benar-benar tidak responsif karena pengelompokan kmeans multi-inti dari 2 Miliar entri (seharusnya sudah diketahui sebelumnya)
Alex
3

UPDATE : Mengubah solusi saya menjadi skrip python yang berdiri sendiri.

Solusi ini telah menyelamatkan saya lebih dari sekali. Semoga bermanfaat bagi orang lain. Skrip python ini akan menemukan kernel jupyter yang menggunakan lebih dari cpu_thresholdCPU dan meminta pengguna untuk mengirim SIGINTke kernel (KeyboardInterrupt). Ini akan terus dikirim SIGINTsampai penggunaan cpu kernel di bawah ini cpu_threshold. Jika ada beberapa kernel yang berperilaku tidak semestinya, pengguna akan diminta untuk menghentikannya masing-masing (diurutkan berdasarkan penggunaan CPU tertinggi hingga terendah). Terima kasih banyak kepada gcbeltramini karena telah menulis kode untuk menemukan nama kernel jupyter menggunakan api jupyter. Skrip ini telah diuji pada MACOS dengan python3 dan membutuhkan notebook jupyter, request, json dan psutil.

Letakkan skrip di direktori beranda Anda dan kemudian penggunaannya terlihat seperti:

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

Kode skrip di bawah ini:

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
sumber