Разбор задачи 1: таблица свойств сигналов
Как подступиться
В таблице 11 сигналов × 6 свойств = 66 клеток. Запоминать их по одной не нужно: для каждого столбца есть простой критерий, и «плюсов» в каждом столбце мало.
| Столбец | Критерий | «+» в задаче |
|---|---|---|
| A. Связан с аппаратным событием | вызван исключением процессора на конкретной инструкции | SIGBUS, SIGFPE |
| B. Останавливает процесс | действие по умолчанию — Stop | SIGSTOP, SIGTTIN |
| C. По инициативе программиста | сигнал посылают явно: kill, raise, abort, sigqueue |
SIGUSR2, SIGSTOP, SIGRTMIN, SIGABRT (+ спорные) |
| D. Нельзя запретить доставку | не блокируется и не перехватывается | SIGKILL, SIGSTOP |
| E. По умолчанию игнорируется | действие по умолчанию — Ign | SIGCHLD (+ SIGCONT с оговоркой) |
| F. Не «слипается» | ставится в очередь, каждый экземпляр доставляется | SIGRTMIN |
Сначала столбцы, потом строки
Заполняйте таблицу по столбцам: пройдитесь по всем сигналам с вопросом «это исключение процессора?», потом «действие Stop?» и так далее. Так меньше ошибок, чем при заполнении по строкам.
Готовая таблица
| Сигнал | A аппар. | B стоп | C прогр. | D не запретить | E игнор. | F не слип. |
|---|---|---|---|---|---|---|
| SIGCHLD | − | − | − | − | + | − |
| SIGKILL | − | − | +/− ¹ | + | − | − |
| SIGABRT | − | − | + | −/+ ² | − | − |
| SIGBUS | + | − | − | − | − | − |
| SIGUSR2 | − | − | + | − | − | − |
| SIGTTIN | − | + | − | − | − | − |
| SIGSTOP | − | + | + | + | − | − |
| SIGRTMIN | − | − | + | − | − | + |
| SIGFPE | + | − | − | − | − | − |
| SIGPIPE | − | − | − | − | − | − |
| SIGCONT | − | −/+ ³ | +/− ³ | −/+ ³ | +/− ³ | − |
Цифрами отмечены спорные ячейки. Поставьте знак и напишите рядом одну фразу из разбора ниже.
Разбор по строкам
SIGCHLD — «− − − − + −»
Ядро посылает его родителю, когда потомок завершился, остановился или продолжил работу. Это программное событие ядра, а не процессора, и не явный вызов программиста. Блокируется. Действие по умолчанию — Ign, отсюда «+» в столбце E. Обычный (не RT) сигнал: если три потомка завершатся, пока сигнал заблокирован, родитель получит один SIGCHLD. Поэтому обработчик вызывает waitpid(-1, &st, WNOHANG) в цикле.
SIGKILL — «− − ¹ + − −»
Безусловное завершение, его нельзя заблокировать, перехватить или проигнорировать: «+» в D. Не останавливает, а завершает. ¹ Столбец C: обычно его посылают явно (kill -9, kill(pid, SIGKILL)) — «+». Но его посылает и само ядро (OOM killer, завершение остальных потоков при exit_group), поэтому многие ставят «−». Пишите, какой вариант выбрали: «посылается явно kill -9, хотя может прийти и от ядра (OOM killer)».
SIGABRT — «− − + ² − −»
Программа вызывает abort() — явная инициатива программиста (часто через assert): «+» в C. Не аппаратный. Действие по умолчанию — Core. ² Столбец D: SIGABRT можно заблокировать и перехватить, но abort() после возврата из обработчика или при блокировке снимает блокировку, восстанавливает действие по умолчанию и посылает сигнал повторно — процесс всё равно завершится. Поэтому ответ «+ с оговоркой» тоже принимают; строгий ответ — «−», ведь sigprocmask блокирует SIGABRT, посланный через kill.
SIGBUS — «+ − − − − −»
Ошибка шины: невыровненное обращение на некоторых архитектурах, обращение к странице файла за его концом через mmap. Возникает при выполнении инструкции — процессор генерирует исключение, ядро превращает его в сигнал. Действие по умолчанию — Core. Заблокировать «аппаратный» SIGBUS бесполезно: ядро всё равно завершит процесс, но формально блокировка разрешена.
SIGUSR2 — «− − + − − −»
Пользовательский сигнал без предопределённого смысла: его посылают только явно, kill(pid, SIGUSR2). Действие по умолчанию — Term. Обычный, слипается.
SIGTTIN — «− + − − − −»
Драйвер терминала посылает его процессу фоновой группы, когда тот пытается читать с терминала. Действие по умолчанию — Stop: «+» в B. Источник — ядро (драйвер tty), не программист. Можно перехватить и заблокировать.
SIGSTOP — «− + + + − −»
Останавливает процесс (Stop), нельзя заблокировать, перехватить или игнорировать. Посылают явно: kill -STOP pid, отладчик. Не путайте с SIGTSTP (Ctrl+Z): тот посылает терминал, и его можно перехватить.
SIGRTMIN — «− − + − − +»
Сигнал реального времени: нет предопределённого смысла, посылают явно, обычно sigqueue со значением. Действие по умолчанию — Term. Главное свойство — ставится в очередь: каждый экземпляр доставляется отдельно, «+» в F. Это единственный RT-сигнал в задаче.
SIGFPE — «+ − − − − −»
Арифметическое исключение процессора: в первую очередь целочисленное деление на ноль (idiv генерирует #DE). Это и есть «связан с аппаратным событием». Действие по умолчанию — Core. Деление на ноль в double по умолчанию даёт inf, а не сигнал.
SIGPIPE — «− − − − − −»
Ядро посылает его процессу, который пишет в канал или сокет, когда все читатели закрыли свой конец. Событие программное, инициатива не программиста (он пишет в канал, а не посылает сигнал). Действие по умолчанию — Term (не игнорируется, именно поэтому серверы ставят signal(SIGPIPE, SIG_IGN)). Обычный, блокируется. Единственная строка из одних «−».
SIGCONT — спорная строка
Продолжает остановленный процесс. Посылают явно: kill -CONT, команды fg/bg в shell — поэтому «+» в C разумен.
³ Спорные места:
- B. Сам он не останавливает — «−». Но «отрицательное» действие тоже связано с остановкой: кто-то ставит «+» с пояснением «влияет на остановку: продолжает».
- D. Если SIGCONT заблокирован, процесс всё равно продолжится: эффект наступает в момент генерации, а не доставки. Обработчик при этом не вызовется. Можно поставить «+» с этим пояснением.
- E. Действие по умолчанию — Cont: если процесс не остановлен, ничего не происходит, по сути игнорируется. В некоторых таблицах значится как «Ign», поэтому «+» допустим.
Не слипается? Нет: обычный сигнал — «−».
Как оформить ответ
Поставьте знаки во всех клетках. Под таблицей одной-двумя строками поясните спорные: «SIGKILL: + в C, т.к. обычно посылается явно kill -9, но может прийти и от ядра (OOM)». «SIGCONT продолжает процесс даже если заблокирован — поэтому + в D». Преподаватель ценит понимание механизма больше, чем конкретный знак.
Шпаргалка
- A: SIGSEGV, SIGBUS, SIGFPE, SIGILL, SIGTRAP — исключения процессора.
- B: SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU — действие Stop.
- D: только SIGKILL и SIGSTOP.
- E: SIGCHLD, SIGURG, SIGWINCH (+ SIGCONT) — действие Ign.
- F: только SIGRTMIN…SIGRTMAX.
Чтобы освежить механизмы, вернитесь к урокам модуля «Сигналы»: источники сигналов, обработка и блокировка, сигналы реального времени и практикум.
Практика решено 0 из 5
Задача 1 экзамена. Заполните таблицу. В спорных ячейках засчитывается любой вариант, но на экзамене рядом нужно написать пояснение (см. разбор под таблицей урока).
| Связан с аппаратным событием | Останавливает процесс (не только завершает) | Выставляется по инициативе программиста | Нельзя запретить доставку | По умолчанию игнорируется | Не «слипается» | |
|---|---|---|---|---|---|---|
| SIGCHLD | ||||||
| SIGKILL | ||||||
| SIGABRT | ||||||
| SIGBUS | ||||||
| SIGUSR2 | ||||||
| SIGTTIN | ||||||
| SIGSTOP | ||||||
| SIGRTMIN | ||||||
| SIGFPE | ||||||
| SIGPIPE | ||||||
| SIGCONT |
Почему у SIGPIPE в столбце «связан с аппаратным событием» стоит «−»?
Чем SIGSTOP отличается от SIGTTIN в этой таблице?
Какие ячейки строки SIGCONT считаются спорными и требуют пояснения?
Сколько всего «+» в столбце «нельзя запретить доставку», если спорные ячейки не считать? (число)
Войдите, чтобы отмечать пройденные уроки.