<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.linuxformat.ru/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF131%3ADrBrown3</id>
		<title>LXF131:DrBrown3 - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF131%3ADrBrown3"/>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF131:DrBrown3&amp;action=history"/>
		<updated>2026-05-13T03:53:17Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.19.20+dfsg-0+deb7u3</generator>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/index.php?title=LXF131:DrBrown3&amp;diff=12013&amp;oldid=prev</id>
		<title>Crazy Rebel: викификация, оформление, иллюстрация</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF131:DrBrown3&amp;diff=12013&amp;oldid=prev"/>
				<updated>2011-05-10T07:10:42Z</updated>
		
		<summary type="html">&lt;p&gt;викификация, оформление, иллюстрация&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Шлем верные сигналы==&lt;br /&gt;
&lt;br /&gt;
: Сигналы Подробное руководство о том, что это, откуда они взялись, куда идут и что происходит при отправке.&lt;br /&gt;
&lt;br /&gt;
Сигнал – событие, отправляемое выполняющейся программе ядром или пользовательским процессом. Сигналы асинхронны, то есть могут приходить когда угодно, и их появление в большинстве случаев никак не связано с тем, что собиралась делать программа. Сигналы обычно означают некое внешнее событие, способное повлиять на выполнение программы. Программа может выбрать, что должно произойти по приходу сигнала определенного типа. Она может игнорировать его (за одним важным исключением); запустить специальный обработчик сигнала и продолжить с того места, где остановилась; или просто выполнить «действие по умолчанию» для этого сигнала, что в большинстве случаев означает завершение процесса.&lt;br /&gt;
&lt;br /&gt;
За исключением сигналов «реального времени», существует 31 тип сигнала. Каждый тип определяется именем (например, '''SIGTERM''') и целым числом (например, '''15'''). Получить список всех типов можно командой:&lt;br /&gt;
&lt;br /&gt;
 $ kill -l&lt;br /&gt;
&lt;br /&gt;
Из этих 31 администратор должен знать, полагаю, шесть. Я свел их в таблицу.&lt;br /&gt;
{|class=wikitable border=1 cellpadding=5|-&lt;br /&gt;
! Имя&lt;br /&gt;
! №&lt;br /&gt;
! Описание&lt;br /&gt;
! Действие по умолчанию&lt;br /&gt;
|-&lt;br /&gt;
| SIGHUP&lt;br /&gt;
| 1&lt;br /&gt;
| Инициирует перенастройку фонового сервиса&lt;br /&gt;
| Завершить процесс&lt;br /&gt;
|-&lt;br /&gt;
| SIGINT&lt;br /&gt;
| 2&lt;br /&gt;
| Ctrl+C с клавиатуры&lt;br /&gt;
| Завершить процесс&lt;br /&gt;
|-&lt;br /&gt;
| SIGQUIT&lt;br /&gt;
| 3&lt;br /&gt;
| Ctrl+\ с клавиатуры&lt;br /&gt;
| Завершить процесс с дампом памяти&lt;br /&gt;
|- &lt;br /&gt;
| SIGKILL&lt;br /&gt;
| 9&lt;br /&gt;
| Суперважный сигнал, который нельзя перехватить или игнорировать&lt;br /&gt;
| Завершить процесс&lt;br /&gt;
|-&lt;br /&gt;
| SIGSEGV&lt;br /&gt;
| 11&lt;br /&gt;
| Программа пыталась обратиться к памяти по неверному адресу&lt;br /&gt;
| Завершить процесс с дампом памяти&lt;br /&gt;
|-&lt;br /&gt;
| SIGTERM&lt;br /&gt;
| 15&lt;br /&gt;
| «Вежливая» просьба закончить работу&lt;br /&gt;
| Завершить процесс&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Сигнал '''SIGHUP''' обычно используется для предупреждения демона (это системный сервис, работающий в фоне), что конфигурационный файл изменен и его нужно перечитать. Многие демоны так и реагируют на '''SIGHUP'''. Примеры включают «суперсервер Интернета» ''xinetd'' и демон системного журнала ''syslogd''. Демонам, поддерживающим '''SIGHUP''', лучше отправить этот сигнал, чем перезапустить их – тогда существующие соединения с клиентами сохранятся, а при останове и перезапуске демона они будут разорваны.&lt;br /&gt;
&lt;br /&gt;
«HUP» – сокращение от «hang up» (повесить трубку). Изначально этот сигнал генерировался драйвером терминала последовательного порта с подключенным на прием звонков модемом. Если телефонное соединение обрывалось, драйвер терминала замечал, что несущая исчезла, и отправлял '''SIGH-UP''' оболочке, завершая ее. Идея состояла в том, чтобы гарантировать, что новый абонент не начнет случайно работать в оболочке предыдущего.&lt;br /&gt;
&lt;br /&gt;
Сигнал '''SIGINT''' посылается активному процессу при нажатии '''Ctrl+C''' в его терминале. Его действие по умолчанию – завершить (убить) процесс. Поэтому «долгоиграющие» задания часто можно прервать, нажав '''Ctrl+C'''. Однако многие программы игнорируют или перехватывают '''SIGINT'''. Например, ''less'' при получении '''SIGINT''' не завершается, а запрашивает ввод команды.&lt;br /&gt;
&lt;br /&gt;
Сигнал '''SIGQUIT''' посылается активному процессу при нажатии '''Ctrl+\''' на клавиатуре. Он используется гораздо реже и менее известен, чем '''SIGINT'''. По умолчанию он также завершает процесс, но заодно заставляет оболочку создать файл '''core''', содержащий образ памяти программы, для «посмертной» отладки. В большинстве дистрибутивов файлы '''core''' запрещены, потому что в настройке процесса ''ulimit'' (которая ограничивает использование ресурсов) максимальный размер файла '''core''' установлен в ноль. Чтобы проверить свои настройки, выполните команду ''ulimit -a'' и поищите встроенную команду ''ulimit'' на ''man''-странице ''bash''.&lt;br /&gt;
&lt;br /&gt;
===Смертоносные сигналы===&lt;br /&gt;
&lt;br /&gt;
Сигнал '''SIGTERM''' отправляется командой ''kill'' по умолчанию. Это вежливая просьба «пожалуйста, приберите за собой и завершитесь». При выключении системы процесс ''init'' отправляет сигналы '''SIGTERM''' всем выполняющимся процессам с просьбой завершиться. Если это не срабатывает, ''init'' применяет более суровые меры...&lt;br /&gt;
&lt;br /&gt;
Сигнал '''SIGKILL''' – самый подлый из всех. Его нельзя перехватить или игнорировать, и его действие – прикончить процесс. Отправка '''SIGKILL''' должна быть крайней мерой, только в том случае, если более благородные '''SIGTERM''' и '''SIGINT''' не сработали. Разница между '''SIGTERM''' и '''SIGKILL''' – как между вежливой просьбой завершиться и выстрелом в голову. '''SIGKILL''' не дает процессу возможности прибраться. Перед перезапуском «убитых» программ, которые временно хранили данные на диске или находились посреди двухфазной фиксации транзакции, может потребоваться ручная расчистка.&lt;br /&gt;
&lt;br /&gt;
Сигнал '''SIGSEGV''' (нарушение сегментации) отличается от прочих описанных здесь тем, что не приходит извне, а обусловлен самой программой. Он подается, когда программа пытается обратиться к адресу памяти вне отведенного ей диапазона. (Это легко сделать в ''C'' и ''C++'', сославшись на неинициализированный указатель). Блок управления памятью видит эту попытку и тихо говорит ядру, которое отправляет '''SIGSEGV''' программе. Действие по умолчанию при получении этого сигнала – завершить программу. Если в программе нет ошибок, такого произойти не должно, но безупречных программ мало, и вы, наверное, видели, как программы падают из-за ошибки нарушения сегментации.&lt;br /&gt;
&lt;br /&gt;
Сигналы '''SIGILL''' (неверная команда), '''SIGBUS''' (ошибка шины) и '''SIGFPE''' (исключение с плавающей точкой) генерируются подобным образом, когда программа пытается сделать такое, чего не разрешает аппаратная часть; но распространены они гораздо меньше. '''SIGSEGV''' легко продемонстрировать. Следующая программа на ''С'' из двух строк генерирует этот сигнал в ответ на попытку записать число по адресу памяти 0:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
 main()&lt;br /&gt;
 { *((int*)0) = 0;}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====История о SIGSEGV====&lt;br /&gt;
&lt;br /&gt;
В первый раз я общался с Unix в так называемой &amp;quot;Edition6&amp;quot;. Я принес на работу копию, которую мне дал коллега в Открытом университете, и установил ее на наш PDP-11/60. На другой день я печатал некоторые man-страницы (другой печатной документации не было) и получил сообщение об «ошибке памяти». Решив, что компьютер неисправен, я выключил Unix и провел остаток дня за диагностикой оборудования, но никаких проблем не обнаружил. В конце концов я узнал, что «ошибка памяти» – это сообщение оболочки о том, что процесс завершился с SIGSEGV. Со временем я выяснил, что многие сообщения об ошибках в Unix были скорее причудами программиста, а не попыткой объяснить, что же на самом деле происходит. Моим любимым было «Это не пишущая машинка».&lt;br /&gt;
&lt;br /&gt;
===Отправка сигналов===&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF131_53_1.jpg|300px]] Сигналы могут возникать в разных местах, но все они передаются ядром.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Все сигналы в конечном счете доставляются ядром, но исходят из различных источников, как показано на рисунке. Для отправки сигналов из командной строки используется команда ''kill'', обычно таким образом:&lt;br /&gt;
&lt;br /&gt;
 $ kill -SIGINT 11434 11559&lt;br /&gt;
&lt;br /&gt;
11434 и 11559 – идентификаторы процессов-приемников.&lt;br /&gt;
&lt;br /&gt;
Отправить сигналы можно только тем процессам, владельцем которых являетесь вы (если вы не root). Вместо имени сигнала допускается его номер; можно также не набирать '''SIG''' в начале имени, поэтому три следующих команды эквивалентны:&lt;br /&gt;
&lt;br /&gt;
 $ kill -SIGKILL 11434&lt;br /&gt;
 $ kill -KILL 11434&lt;br /&gt;
 $ kill -9 11434&lt;br /&gt;
&lt;br /&gt;
Команда называется «''kill''», потому что во многих случаях ее результатом становится завершение процесса; но это не самое лучшее имя. «Throw» [выбросить] или «send-signal» [послать сигнал] было бы лучше.&lt;br /&gt;
&lt;br /&gt;
Неудобство ''kill'' в том, что нужно знать числовой идентификатор процесса. Команда ''pkill'' позволяет задать процессы, которым отправляются сигналы, другими способами. Вот три примера:&lt;br /&gt;
&lt;br /&gt;
 $ pkill -SIGHUP syslogd&lt;br /&gt;
 $ pkill -SIGTERM -U fred&lt;br /&gt;
 $ pkill -SIGKILL -P 13579&lt;br /&gt;
&lt;br /&gt;
Первый сигнал отправляется всем процессам, выполняющим ''syslogd''. Второй – всем процессам, владельцем которых является '''fred''', а третий – всем процессам, чей родительский PID 13579.&lt;br /&gt;
&lt;br /&gt;
В оболочке есть встроенная команда ''trap'', упрощающая обработку сигнала в сценариях без необходимости сочинять нудный код на ''C'', как делают записные хакеры. ''Trap'' принимает два аргумента: команду (или набор команд) и имя сигнала, и обеспечивает выполнение указанных команд при получении сигнала с заданным номером. Попробуйте создать такой скрипт:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 trap ‘echo I got a SIGHUP signal’ SIGHUP&lt;br /&gt;
 trap ‘echo Terminating on SIGTERM; exit 1’ SIGTERM&lt;br /&gt;
 while true&lt;br /&gt;
 do&lt;br /&gt;
 	 sleep 1;&lt;br /&gt;
 	 date&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сделайте его исполняемым и запустите в фоне – так вы легко сможете узнать идентификатор процесса:&lt;br /&gt;
&lt;br /&gt;
 $ chmod u+x trapdemo&lt;br /&gt;
 $ ./trapdemo &amp;amp;&lt;br /&gt;
 [1] 18729&lt;br /&gt;
&lt;br /&gt;
Скрипт печатает дату и ждет секунду. Поэкспериментируйте с командой ''kill'', отправляя сигналы различных типов с другого терминала. При отправке '''SIGHUP''' скрипт сообщит, что получил сигнал, и продолжит работу. В ответ на '''SIGTERM''' он выведет сообщение и завершится. При получении любого другого сигнала выполнится действие по умолчанию.&lt;br /&gt;
&lt;br /&gt;
===Советы программистам===&lt;br /&gt;
&lt;br /&gt;
Программистам также могут быть интересны различные сигналы, но им нужно разбираться в сигналах слегка по иным причинам. Наверное, главное, что нужно знать программисту о сигналах – как заставить программу игнорировать их. Причин такого поведения может быть множество, но надо уметь обращаться с сигналами не только затем, чтобы просто наделить процессы возможностью выживания: сигналы обеспечивают обратную связь от системы.&lt;br /&gt;
&lt;br /&gt;
Вот еще несколько вещей, для которых программисту могут пригодиться сигналы:&lt;br /&gt;
* обработать '''SIGHUP''' для перечитывания конфигурационных файлов, обычно для демонов;&lt;br /&gt;
* обработать '''SIGTERM''', чтобы убрать за собой и корректно завершить работу;&lt;br /&gt;
* обработать '''SIGCHLD''', чтобы асинхронно собрать результаты завершения дочерних процессов;&lt;br /&gt;
* обработать '''SIGALRM''' для реализации таймаута при блокирующих операциях;&lt;br /&gt;
* обработать '''SIGUSR1''' (или другой сигнал по вашему выбору), чтобы сообщить текущий статус процесса;&lt;br /&gt;
* использовать сигнал, чтобы динамически включать и выключать отладочные сообщения.&lt;br /&gt;
&lt;br /&gt;
Если вы серьезно заинтересовались сигналами с точки зрения программиста, раздобудьте книгу Ричарда Стивенса «UNIX. Профессиональное программирование» и погрузитесь в ее десятую главу.&lt;br /&gt;
&lt;br /&gt;
===Сигналы и статус выхода===&lt;br /&gt;
&lt;br /&gt;
Если программа запускается из командной строки и завершается сигналом, в оболочке появится сообщение об этом. Например, при завершении программы сигналом '''SIGTERM''' оболочка выводит сообщение “Terminated”. Для программы, убитой сигналом '''SIGKILL''', выводится сообщение “Killed”, а для программы, совершившей самоубийство попыткой обратиться по неверному адресу памяти – сообщение “Segmentation fault”. По статусу выхода оболочка знает, что процесс завершен сигналом.&lt;br /&gt;
&lt;br /&gt;
У программы, завершившейся нормально, статус выхода равен нулю. Программа, которая (добровольно) завершается с ошибкой, возвратит статус выхода в диапазоне 1–127. А программа, завершенная сигналом, возвратит статус выхода, равный 128 плюс номер соответствующего сигнала. Мы можем увидеть это, запустив заведомо кривую программу на ''C'' и просмотрев статус выхода путем вывода значения специальной переменной оболочки '''$?'''&lt;br /&gt;
&lt;br /&gt;
 $ ./forcesignal&lt;br /&gt;
 Segmentation fault&lt;br /&gt;
 $ echo $?&lt;br /&gt;
 139&lt;br /&gt;
&lt;br /&gt;
Здесь статус выхода 139 (128+11) сообщает нам о том, что программа завершилась по сигналу 11 ('''SIGSEGV'''), что мы преднамеренно и пытались спровоцировать.&lt;/div&gt;</summary>
		<author><name>Crazy Rebel</name></author>	</entry>

	</feed>