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_threshold
CPU dan meminta pengguna untuk mengirim SIGINT
ke kernel (KeyboardInterrupt). Ini akan terus dikirim SIGINT
sampai 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()