Остановка python с помощью ctrl + c

128

У меня есть скрипт на Python, который использует потоки и выполняет множество HTTP-запросов. Я думаю, что происходит то, что пока HTTP-запрос (с использованием urllib2) читает, он блокируется и не отвечает, CtrlCчтобы остановить программу. Есть ли способ обойти это?

jonatron
источник
9
Я не знаю почему, но, по крайней мере, в OS X использование Control + Backslash приводит к его завершению, и вы получаете диалоговое окно «python сбой» ... странно. Не совсем полезная информация, поэтому это комментарий!
micmoo 01
3
На самом деле он работает во всех приложениях в Терминале ...
micmoo 01
1
Дэвид Бизли описал, как прерывание Ctrl / C может превратить многопоточный скрипт Python в нагрузку на процессор. Это затронуто здесь ( stackoverflow.com/questions/990102/… ) со ссылкой на доклад Бизли.
Нед Дейли, 02

Ответы:

189

В Windows единственный верный способ - использовать CtrlBreak. Мгновенно останавливает каждый скрипт Python!

(Обратите внимание, что на некоторых клавиатурах «Перерыв» помечен как «Пауза».)

Денис Масюков
источник
4
Что есть Break? Как мне это набрать?
u0b34a0f6ae 01
5
На клавиатуре должна быть кнопка
Pause_Break
18
Что, если нет? Я использую Intel Macbook, и у него не очень полнофункциональная клавиатура.
Bluu
53
В Linux вы должны использовать Ctrl-Shift- \
Michał Zieliński
12
ctrl + Z не убивает скрипт, а просто скрывает его на заднем плане и приостанавливает его. Вы можете набрать fg, чтобы вызвать его.
Shady Xu
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.
Xerion
53

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

Эндрю Хэйр
источник
25
^Z-> [1]+ Stopped -> kill %1чтобы остановить задание №1 (или задание% 1, как выразился bash)
u0b34a0f6ae 01
23
К ответу стоит добавить, что Ctrl + Z просто приостанавливает процесс.
Маттео Италия,
2
Чтобы уточнить вышесказанное: приостановка процесса сохраняет его в памяти и в вашей оболочке, это просто не позволяет ему использовать ресурсы ЦП. Файлы, сокеты, все еще открыто и используется. Фактически, набор fgвернет его обратно.
RandomInsano,
2
Ctrl+Z- неправильный способ остановить скрипт Python, и его следует избегать, если вы не планируете возобновлять приостановленный процесс.
Джош Коррейя,
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) может жить собственной жизнью ...

not2qubit
источник
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+\

Окна :

  • Общие: Ctrl+Break
  • Dell: Ctrl+ Fn+ F6или Ctrl+ Fn+S
  • Lenovo: Ctrl+ Fn+ F11или Ctrl+ Fn+B
  • HP: Ctrl+ Fn+Shift
  • Samsung: Fn+Esc

Решение 2. Используйте Windows 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, подключенного к терминалу.

Krunal
источник
3

На Mac / в Терминале:

  1. Показать инспектор (щелкните правой кнопкой мыши в окне терминала или «Оболочка»> «Показать инспектор»)
  2. щелкните значок настроек над "запущенными процессами"
  3. выберите из списка опций в «Signal Process Group» (Kill, terminate, interrupt, и т. д.).
AG452
источник
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 + pause, но как только вы завершите задачу python (та, которая использует 63,7 мб), она выйдет из сценария сервера в bash и позволит мне использовать оболочку git bash. введите описание изображения здесь

Джордано
источник
1

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

Bertinchamps
источник