Зупинка python за допомогою ctrl + c


128

У мене є сценарій python, який використовує нитки та робить безліч HTTP-запитів. Я думаю, що відбувається в тому, що хоч HTTP-запит (за допомогою urllib2) читає, він блокує і не реагує CtrlCна зупинку програми. Чи є спосіб обходити це?


9
Я не знаю чому, але, принаймні, на OS X, використання Control + Backslash змушує його припинятись, і ви отримуєте діалог "python crashed" ... дивно. Не дуже корисна інформація, тому це коментар!
micmoo

3
Насправді він працює на всіх додатках у Терміналі ...
micmoo

1
Девід Бізлі описав, як переривання Ctrl / C може перетворити сценарій Python, що має багатопотужну версію, в свиню CPU. Це торкається тут ( stackoverflow.com/questions/990102/… ) із посиланням на розмову Бізлі.
Нед Дейлі

Відповіді:


189

У Windows єдиний вірний спосіб - це використання CtrlBreak. Зупиняє кожен сценарій python миттєво!

(Зверніть увагу, що на деяких клавіатурах "Перерва" позначений як "Пауза".)


4
Що таке Break? Як ввести його?
u0b34a0f6ae

5
На вашій клавіатурі повинна бути кнопка "
Pause_Break"

18
Що робити, якщо його немає? Я на Intel Macbook, і він не має дуже повнофункціональної клавіатури.
Блу

53
В Linux вам слід використовувати Ctrl-Shift- \
Michał Zieliński

12
ctrl + Z не вбиває сценарій, він просто приховує його на задній план і призупиняє його. Ви можете ввести fg, щоб відкликати його.
Шаді Сю

84

Натискання Ctrl+ cпід час запуску програми python призведе до того, що python створить KeyboardInterruptвиняток. Ймовірно, що програма, яка робить безліч запитів HTTP, матиме безліч код обробки винятків. Якщо exceptчастина try- exceptблок не визначає , які винятку він повинен зловити, він буде перехоплювати всі виключення , в тому числі , KeyboardInterruptщо ви тільки що викликали. Правильно кодована програма python буде використовувати ієрархію винятків python та вловлювати лише винятки, похідні від Exception.

#This is the wrong way to do things
try:
  #Some stuff might raise an IO exception
except:
  #Code that ignores errors

#This is the right way to do things
try:
  #Some stuff might raise an IO exception
except Exception:
  #This won't catch KeyboardInterrupt

Якщо ви не можете змінити код (або потрібно вбити програму, щоб зміни вступили в силу), ви можете спробувати натиснути Ctrl+ cшвидко. Перший з KeyboardInterruptвинятків виведе вашу програму з tryблоку, і, сподіваємось, одне з пізніших KeyboardInterruptвинятків буде піднято, коли програма знаходиться поза tryблоком.


1
Це чудова відповідь, щоб увімкнути найпоширеніший "перелом", який є ctrl + c
Ксеріон

53

Якщо він працює в оболонці Python, використовуйте Ctrl+ Z, інакше знайдіть pythonпроцес і вбийте його.


25
^Z-> [1]+ Stopped -> kill %1припинити роботу №1 (або роботу% 1, як
башти

23
Варто додати у відповідь, що Ctrl + Z просто призупиняє процес.
Маттео Італія

2
Щоб детальніше зупинитися на вищезазначеному: Призупинення процесу зберігає його в пам’яті та вашій оболонці, воно просто заважає використовувати ресурси CPU. Файли, розетки, все ще відкрито і використовується. Насправді введення тексту fgповерне це назад.
RandomInsano

2
Ctrl+Zце не правильний спосіб зупинити скрипт пітона, і його слід уникати, якщо ви не плануєте відновити призупинений процес.
Джош Коррея

33

Процес переривання залежить від обладнання та ОС. Таким чином, у вас буде дуже різна поведінка залежно від того, де ви запускаєте свій скрипт python. Наприклад, на машинах Windows у нас є Ctrl+ C( SIGINT) і Ctrl+ Break(SIGBREAK ).

Отже, хоча SIGINT присутній у всіх системах і може оброблятися та перехоплюватися, сигнал SIGBREAK є специфічним для Windows (і його можна відключити в CONFIG.SYS ) і справді обробляє BIOS як вектор переривання INT 1Bh , саме тому ця клавіша набагато потужніший за будь-який інший. Тож якщо ви використовуєте деяку ОС * з ароматизованим * nix, ви отримаєте різні результати залежно від реалізації, оскільки цього сигналу немає, але інші є. У Linux ви можете перевірити, які сигнали доступні вам:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGEMT       8) SIGFPE       9) SIGKILL     10) SIGBUS
11) SIGSEGV     12) SIGSYS      13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGURG      17) SIGSTOP     18) SIGTSTP     19) SIGCONT     20) SIGCHLD
21) SIGTTIN     22) SIGTTOU     23) SIGIO       24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGPWR      30) SIGUSR1
31) SIGUSR2     32) SIGRTMAX

Тож якщо ви хочете зафіксувати CTRL+BREAK сигнал у системі Linux, вам доведеться перевірити, на який POSIX-сигнал вони вказали цей ключ. Популярні карти:

CTRL+\     = SIGQUIT 
CTRL+D     = SIGQUIT
CTRL+C     = SIGINT
CTRL+Z     = SIGTSTOP 
CTRL+BREAK = SIGKILL or SIGTERM or SIGSTOP

Насправді в Linux є багато інших функцій, де SysRqклавіша (System Request) може взяти на себе життя ...


19

Ця публікація стара, але я нещодавно зіткнувся з тією ж проблемою Ctrl+ Cне припиняти сценарії Python в Linux. Я використав Ctrl+ \( SIGQUIT).


Хоча це призведе до скидання ядра, але сценарій зупиняє, спасибі
ospider

17

Ctrl+ DРізниця для Windows та Linux

Виявляється, що з Python 3.6 інтерпретатор Python Ctrl+ по- Cрізному обробляє для Linux та Windows. Для Linux Ctrl+ Cпрацюватиме в основному так, як очікувалося, однак для Windows Ctrl+ C здебільшого не працює, особливо якщо Python виконує блокування викликів, таких як thread.joinабо очікування відповіді в Інтернеті. Це time.sleep, однак, працює. Ось приємне пояснення того, що відбувається в інтерпретаторі Python. Зауважте, що Ctrl+ Cгенерує SIGINT.

Рішення 1: Використовуйте Ctrl+ Breakабо еквівалент

Використовуйте нижче комбінації клавіш у вікні термінала / консолі, які будуть генеруватися SIGBREAKна нижчому рівні в ОС та припиняти інтерпретатор Python.

Mac OS та Linux

Ctrl+ Shift+ \або Ctrl+\

Windows :

  • Загальне: Ctrl+Break
  • Dell: Ctrl+ Fn+ F6або Ctrl+ Fn+S
  • Lenovo: Ctrl+ Fn+ F11або Ctrl+ Fn+B
  • HP: Ctrl+ Fn+Shift
  • Samsung: Fn+Esc

Рішення 2: Використовуйте API API

Нижче представлені зручні функції, які виявлять Windows та встановлять користувальницький обробник для Ctrl+ Cу консолі:

#win_ctrl_c.py

import sys

def handler(a,b=None):
    sys.exit(1)
def install_handler():
    if sys.platform == "win32":
        import win32api
        win32api.SetConsoleCtrlHandler(handler, True)

Ви можете використовувати вище, як це:

import threading
import time
import win_ctrl_c

# do something that will block
def work():
    time.sleep(10000)        
t = threading.Thread(target=work)
t.daemon = True
t.start()

#install handler
install_handler()

# now block
t.join()

#Ctrl+C works now!

Рішення 3: Метод опитування

Я не віддаю перевагу або не рекомендую цей метод, оскільки він зайво споживає процесор і потужність, негативно впливаючи на продуктивність.

час імпорту нитки імпорту

def work():
    time.sleep(10000)        
t = threading.Thread(target=work)
t.daemon = True
t.start()
while(True):
    t.join(0.1) #100ms ~ typical human response
# you will get KeyboardIntrupt exception

Ні, на Ubuntu, і для python 2.7 та 3.6, натискання ctrl + cне вимикається, а показує KeyboardInterrupt.
Рік

7

На Mac натисніть Ctrl+, \щоб вийти з процесу python, приєднаного до терміналу.


3

На mac / у Терміналі:

  1. Показати інспектора (клацніть правою кнопкою миші у вікні терміналу або оболонкою> Показати інспектора)
  2. натисніть піктограму "Налаштування" вище "запущені процеси"
  3. виберіть із списку опцій у "Група процесів сигналу" (вбити, припинити, перервати тощо).

1
  • Примушування програми закрити за допомогою Alt + F4 (вимикає поточну програму)
  • Спам-кнопка X на CMD для напр
  • Управління завданнями (спочатку Windows + R, а потім "taskmgr"), а потім закінчити завдання.

Вони можуть допомогти.


1

Ви можете відкрити свій диспетчер завдань (ctrl + alt + delete, потім перейти до диспетчера завдань) і подивитися через нього на python, а сервер викликається (наприклад) _go_app (умова іменування: _language_app).

Якщо я закінчу завдання _go_app, він закінчить сервер, тому, переходячи туди в браузері, він скаже це "несподівано закінчилося", я також використовую git bash, і коли я запускаю сервер, я не можу вирватися з сервера в оболонці bash з ctrl + c або ctrl + пауза, але як тільки ви закінчите завдання python (те, що використовує 63,7 mb), воно вирветься із серверного скрипту в bash і дозволить мені використовувати оболонку git bash. введіть тут опис зображення


1

Для запису, те, що вбило процес на моєму Raspberry 3B + (запущений raspbian), було Ctrl+ '. На моїй французькій клавіатурі AZERTY натисканням 'є також номер 4.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.