IPython Notebookを使い始め、楽しんでいます。ときどき、大量のメモリを必要とするバグや無限ループを含むバグのあるコードを作成します。 「割り込みカーネル」オプションの動作が遅い、または信頼性が低いことがわかりました。カーネルを再起動して、メモリ内のすべてを失うことがあります。
また、OS Xのメモリ不足を引き起こすスクリプトを作成することもありますが、ハードリブートを行う必要があります。 100%確信はありませんが、以前にこのようなバグを書いて、ターミナルでPythonを実行したとき、通常は CTRL+C 私のスクリプト。
Mac OS X上のFirefoxでIPythonノートブックのAnacondaディストリビューションを使用しています。
私は間違っている可能性がありますが、「割り込みカーネル」ボタンは現在実行中のコードにSIGINTシグナルを送信するだけであると確信しています(このアイデアはFernandoのコメント here でサポートされています)これは、CTRL + Cを押すのと同じことです。 python内の一部のプロセスは、他のプロセスよりもSIGINTを突然処理します。
IPython Notebookで実行中の何かを必死に停止する必要があり、端末からiPython Notebookを起動した場合、その端末でCTRL + Cを2回押してiPython Notebookサーバー全体を中断できます。これにより、iPython Notebookがすべて停止します。つまり、作業を再開したり保存したりすることはできません。したがって、これは明らかに優れたソリューションではありません(Ctrl + Cを2回押す必要があります。偶然にそれを行う)。ただし、緊急の場合、通常は「カーネルの割り込み」ボタンよりも速くプロセスを強制終了します。
I
を2回押すと、カーネルを中断できます。
これは、コマンドモードの場合にのみ機能します。まだ有効になっていない場合は、を押します Esc 有効にします。
上記に追加するには:割り込みが機能しない場合は、カーネルを再起動できます。
カーネルドロップダウン>>再起動>>再起動して、出力を消去します。これは通常、トリックを行います。それでも解決しない場合は、ターミナル(またはタスクマネージャー)でカーネルを強制終了してから再起動します。
割り込みはすべてのプロセスでうまく機能しません。私は特にRカーネルを使用してこの問題を抱えています。
UPDATE:ソリューションをスタンドアロンpythonスクリプトに変えました。
このソリューションは私を何度も助けてくれました。うまくいけば、他の人がそれを役に立つと思うでしょう。このpythonスクリプトは、cpu_threshold
CPU以上を使用するjupyterカーネルを検出し、ユーザーにSIGINT
をカーネルに送信するように求めます(KeyboardInterrupt)。カーネルのCPU使用率がcpu_threshold
を下回るまで、SIGINT
を送信し続けます。複数の動作不良のカーネルが存在する場合、各カーネルに割り込みを求めるプロンプトが表示されます(CPU使用率が高い順に並べられます)。 jupyter apiを使用してjupyterカーネルの名前を見つけるコードを記述してくださった gcbeltramini に深く感謝します。このスクリプトはpython3を使用してMACOSでテストされており、jupyterノートブック、リクエスト、json、psutilが必要です。
スクリプトをホームディレクトリに配置すると、使用方法は次のようになります。
python ~/interrupt_bad_kernels.py
Interrupt kernel chews cpu.ipynb; PID: 57588; CPU: 2.3%? (y/n) y
以下のスクリプトコード:
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()