Может ли Ctrl + C отправить сигнал SIGINT нескольким процессам?

Вы, вероятно, сочтете это довольно трудным, и существует очень мало примеров, из которых вы могли бы узнать, как это сделать.

Когда вы говорите «терминал», большинство читателей предполагает, что вы говорите о чем-то вроде xterm или rxvt: эмуляторе терминала. Технически консоль Linux также является эмулятором терминала.

Терминалы рисуют только один символ в каждой ячейке (строке и столбце) своего окна / дисплея. Фоны - это то, на чем не рисуется: пустые места. Кто-то мог бы написать приложение с символьными ячейками на основе screen или tmux, которое могло бы записывать тусклые символы из вашего анимированного фона, при нормальном рендеринге «реального» текста. Даже с dim результат будет трудночитаемым.

Некоторые терминалы имеют возможность рисовать графическое изображение в качестве фона; некоторые из них могут имитировать прозрачные окна, копируя корневое окно в свое окно. (Это отличается от гораздо более поздней альфа-прозрачности, поддерживаемой некоторыми серверами графического отображения).

Однако те терминалы, которые рисуют графическое изображение, создают статический дисплей, который может обновляться в ответ на перемещение окна терминала по экрану. Нет никаких технических причин, по которым (кроме проблем с производительностью) терминал не мог отображать анимированный фон. Но на практике вы найдете несколько реализаций, которые делают , что (мало кому интересно, мало разработчиков и т. Д.).

3
16.05.2017, 21:53
3 ответа

Поскольку все новые процессы принадлежат к одной и той же группе процессов, группе родительского процесса, процесс запускает группу процессов (fork), а затем с соответствующим протоколированием и задержкой введите control+c. Все они едят SIGINT.

$ perl -E 'fork for 1..2;say "ima $$"; $SIG{INT}=sub{die "woe $$\n"}; sleep 999'
ima 80920
ima 80922
ima 80921
ima 80923
^Cwoe 80920
woe 80922
woe 80921
woe 80923
$ 

(Добавьте strace или sysdig или что-то подобное, чтобы увидеть задействованные системные вызовы или сигналы.)

2
27.01.2020, 21:18

конвейер — это одно заданиес несколькими процессами:

(cat ; echo foo >&2) | (cat ; echo bar >&2 )

Если вы закончите ввод ^D, вы получите fooи bar, если вы уничтожите конвейер с помощью ^C, ни один из них не будет напечатан.

2
27.01.2020, 21:18

Один пример:

bash-4.3$ ( ( sleep 2 & (ps -Hfj | sh -c cat; perl -MPOSIX -E 'say tcgetpgrp 0'; sleep 5;:);:);:)
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
chazelas 18631  3848 18631 18631  0 12:51 pts/7    00:00:00 /bin/zsh
chazelas  2184 18631  2184 18631  0 21:00 pts/7    00:00:00   bash --norc
chazelas  2430  2184  2430 18631  0 21:07 pts/7    00:00:00     bash --norc
chazelas  2431  2430  2430 18631  0 21:07 pts/7    00:00:00       bash --norc
chazelas  2432  2431  2430 18631  0 21:07 pts/7    00:00:00         sleep 2
chazelas  2433  2431  2430 18631  0 21:07 pts/7    00:00:00         bash --norc
chazelas  2434  2433  2430 18631  0 21:07 pts/7    00:00:00           ps -Hfj
chazelas  2435  2433  2430 18631  0 21:07 pts/7    00:00:00           sh -c cat
chazelas  2436  2435  2430 18631  0 21:07 pts/7    00:00:00             cat
2430

В то время ps был запущен, в группе процессов 2430 было 7 процессов: 3 процесса подоболочки (bash), один работающий ps, один работающий sh, одна работающая кошка, одна работающая спящая 1. Позже процессы, созданные для выполнения perl и sleep 5, также будут в той же группе.

tcgetpgrp() подтверждает, что 2430 действительно была группой процессов переднего плана терминального устройства, поэтому при нажатии Ctrl+C все процессы в этой группе получат сигнал SIGINT.

0
27.01.2020, 21:18

Теги

Похожие вопросы