Несколько раз нажатие ctrl-c заставляет запущенную программу закрываться быстрее?


41

Я часто начинаю читать огромный файл, а затем через некоторое время хочу выйти, но есть задержка от нажатия
Ctrl+ Cдо остановки программы. Есть ли шанс сократить отставание, нажав клавишу Ctrl+ Cнесколько раз? Или я трачу свои клавиши?


Я заметил, что при запуске процесса, который вызывает различные дочерние процессы, Ctrl-C иногда прерывает работающий дочерний процесс, но не родительский процесс. Это верно в отношении bash, но не в случае, zshкогда всегда закрывается родитель. Это одна из причин, по которой мне нравится zsh.
Joeytwiddle

17
Да, точно так же, как повторное нажатие кнопки лифта или кнопки перекрестного движения приведет к тому, что лифт прибудет раньше, или индикатор станет зеленым быстрее.
Майкл

3
Да, точно так же, как кнопки лифта и пешеходного перехода, CTRL-C может также стать липким или ржавым или создать ненадежные соединения. Нажатие несколько раз является хорошей тактикой, потому что только одно нажатие должно быть зарегистрировано, чтобы подняться на лифте, чтобы загорелся знак ходьбы или чтобы программа закрылась.
hippietrail

1
@hippietrail, но ваша оболочка будет распечатываться, ^Cкогда она регистрирует прессу (по крайней мере, это делает bash)
wchargin

1
Что бы это ни стоило, я не считаю, что это тратит впустую мои нажатия клавиш - я считаю, что это дает некоторое разочарование не повреждающим способом. (Я обычно нажимаю на него 2-3 раза, но это отчасти потому, что я «вырос» на терминалах, подключенных к телефонным линиям, где вы не всегда можете рассчитывать на каждое нажатие клавиши на машине.)
keshlam

Ответы:


35

После первого Ctrl-Cпрограмма получит SIGINTи, как правило, начнет очистку (удаление файлов tmp, закрытие сокетов и т. Д.). Если вы нажмете еще Ctrl-Cраз, пока это происходит, может случиться так, что вы прервете процедуру очистки (т. Е. Дополнительный сигнал может сработать вместо того, чтобы остаться один), оставив беспорядок. Хотя обычно это не так, чаще всего дополнительные сигналы фактически отправляются после процесс завершил (из-за внутренних задержек во взаимодействии оператора с системой). Это означает, что сигналы получен другим процессом (часто оболочкой, но не всегда). Если этот получатель не обрабатывает этот сигнал должным образом (как обычно это делает оболочка - см. ответ Дженни Д.), вы можете быть неприятно удивлены результатом такого действия.


Почему это должно прерывать процедуру очистки? Это просто еще один сигнал, INTкоторый получает процесс.
хаос

4
@chaos Зачем это нужно? Это должно произойти, если процедура очистки зависла, и вы хотите остановить ее. Это действительно работает таким образом? Да, довольно часто Вы можете продемонстрировать это достаточно просто: создайте bash-скрипт одной строкой trap "sleep 20 || echo clean up cancelled!" EXIT ; sleep 10. Запустите скрипт и дважды нажмите Ctrl-C. Вы увидите, что второй ctrl-C передается подпрограмме «clean» (в операторе trap) и завершает свою sleepкоманду.
John1024

1
@ John1024 Ах, теперь я вижу это. Спасибо за фрагмент сценария ^^ Но очистка не отменяется, см .: trap "sleep 20 || echo clean up cancelled!; sleep 10; echo 'but continued'" EXIT ; sleep 10только sleepкоманды получают сигналы. Мы оба были неправы xD
хаос

2
Это неверно Доставка сигнала синхронная. Если isigон включен, как только ядро ​​нажмет и получит CTRL-C (для эмулятора терминала, как только эмулятор терминала запишет его на ведущую сторону псевдотерминала), сигнал SIGINT отправляется на все процессы на переднем плане процессов группы терминала. Он может быть заблокирован там, но не будет доставлен позже другому процессу. Даже если буфер терминального устройства заполнен (приложения не читают ничего из того, что вы ввели), CTRL-C будет переходить в очередь.
Стефан Шазелас

1
Да, в качестве примера, VLC интерпретирует несколько сигналов Ctrl + C как способ нечистого выхода, тогда как один Ctrl + C будет пытаться выйти из него чисто.
Джереми Виссер

11

Ты их тратишь. Все, что происходит, это то, что, как только сервер завершит вывод на экран, он получит несколько Ctrl-C. Первый будет использоваться для уничтожения процесса, а следующие будут в вашей оболочке, которая будет выглядеть примерно так:

[user@server]$ ^C
[user@server]$ ^C
[user@server]$ ^C
[user@server]$ ^C
[user@server]$ ^C
[user@server]$ 

6
Процесс не обязательно завершается при отправке SIGINT. Он может остаться в живых до бесконечности и делать что-то новое каждый раз, когда нажимаются Ctrl + C.
Брайан Гордон

Правда. Я делал предположения о том, как пользователь читает файл.
Дженни Д

5

короткий ответ: если процесс реагирует на это.

Длинный ответ: Когда вы нажимаете ctrl+, cядро посылает сигнал процессу. Какой сигнал можно определить с помощью следующей команды:

user@host:~# stty -a | grep -i "\^C"
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;

Смотрите справочную страницу stty:

   intr CHAR
          CHAR will send an interrupt signal

Это сигнал INT, также известный как номер 2. Когда процесс имеет обработчик сигнала, он может реагировать на это. Большинство процессов выполняют некоторые задания по очистке для успешного завершения.


Ctrl-Z обычно отправляет SIGTSTP, который может быть обработан (в отличие от SIGSTOP).
Петер

4
Нет, это не оболочка, которая отправляет SIGINT в процесс. Это kernel(линия дисциплины терминала, терминал водителя) , который посылает SIGINT каждому процессу в процессе переднего плана группы терминала.
Стефан Шазелас

Будущие читатели, также см. Unix.stackexchange.com/a/120071/135943 .
Wildcard

4

Вы правы. Клавиши нажимаются впустую. Когда вы нажимаете, Crtl+Cи он обнаруживается, существуют ресурсы, которые необходимо очистить, поэтому для этого требуется время. Я знаю один возможный случай, когда Ctrl+Cтребуется нажатие , - это когда вы хотите отменить процесс обновления Yum, когда Yum требует, чтобы вы Ctrl+Cдважды нажали, чтобы подтвердить, что вы действительно хотите отменить.


2

Хотя Ctrl-Cв общем случае необходим только один, в некоторых случаях это может быть необходимо. Например, Python перехватывает ловушку, Ctrl-Cкогда создается новый поток, и поэтому, если что-то идет не так в процессе запуска множества потоков, необходимо повторно отправить его несколько раз, чтобы он мог пройти к pythonродительскому процессу без пойманы.


1
Это происходит со мной время от времени, когда я создаю многопоточные / обработанные скрипты Python. Иногда требуется несколько нажатий, прежде чем основной процесс будет убит.
Лев

0

Я всегда должен нажимать Ctrlcнесколько раз. У меня никогда не было ответа на первое нажатие, и мне приходилось использовать его несколько раз, пока система фактически не поймет, Ctrlcчто отправляется. Кажется, что он на самом деле пропускает / теряет большинство из них.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.