업데이트 : 내 솔루션을 독립 실행 형 파이썬 스크립트로 바꿨습니다.
이 솔루션은 저를 두 번 이상 구했습니다. 다른 사람들이 유용하다고 생각하기를 바랍니다. 이 Python 스크립트는 cpu_threshold
CPU 이상을 사용하는 모든 jupyter 커널을 찾고 사용자에게 SIGINT
커널 (KeyboardInterrupt) 을 보내도록 프롬프트합니다 . SIGINT
커널의 CPU 사용량이 아래로 떨어질 때까지 계속 전송 합니다 cpu_threshold
. 오작동하는 커널이 여러 개있는 경우 각 커널을 중단하라는 메시지가 표시됩니다 (가장 높은 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 __name__ == '__main__':
interrupt_bad_notebooks()