Ответ 2
Я предполагаю, что только исключения (программные прерывания) уведомляются через сигналы. Что касается случая аппаратных прерываний.
С чего начать? Там много разных случаев. Имейте в виду, что прерывания - это аппаратное обеспечение, вызывающее процессор. Прерывания в основном состоят из "потребности в аппаратном обеспечении" и числа от 0 до 255. Сигналы схожи, но имеют 2 параметра: идентификатор процесса назначения и int (32 бит или 64 бит, в зависимости от дуги). Аппаратные прерывания всегда обрабатываются в пространстве ядра, тогда как сигналы - это только пользовательские пространства. Ядро использует аппаратные прерывания по разным причинам.
Одним из примеров аппаратного прерывания, которое не имеет ничего общего с сигналами, является подсистема VM. Вы знаете, что в современных операционных системах вы можете выделить больше памяти, чем на самом деле в системе. Так, как это работает? Ну, это работает, используя аппаратные прерывания. Когда вы выделяете память, ядро замечает ее, но на самом деле ничего не делает. Затем, когда вы пытаетесь получить доступ к выделенной памяти, процессор будет жаловаться "но эта память не существует", которая будет генерировать аппаратное прерывание. Ядро пойдет и просмотрит его заметки, найдет, что вы действительно запросили эту память, очистите память, которую она имеет бесплатно, и сообщите процессору "отобразить" эту память в ожидаемом месте. После чего ядро возобновляет вашу программу в точке непосредственно перед тем, как произойдет аппаратное прерывание, и на этот раз процесс найдет память просто отлично.
Многозадачность также реализуется с помощью аппаратного прерывания. Все драйверы обычно работают, интерпретируя прерывания.
Сигналы используются для связи между процессами. Что-то очень "signal-y" было бы общим поведением для демонов linux для перезагрузки их конфигурации на SIGHUP, любимых и ненавистных системными администраторами по всем местам. Когда вы изменяете, скажем, конфигурацию apache, процесс автоматически не запускает новую конфигурацию. Вы можете завершить и перезапустить процесс, но это означает, что через 4-5 секунд ваш HTTP-сервер будет выходить из эфира. Поэтому вместо этого вы можете "killall -HUP apache". Это вызовет подпрограмму в процессе apache, которая заставит ее перечитать ее конфигурационный файл.
Процесс приостановки осуществляется через сигналы (ctrl-z), прерывание процесса (ctrl-c), завершение процесса (ctrl-), терминальные разъединения (sighup),... более полный список можно найти здесь: http://en.wikipedia.org/wiki/Unix_signal.
Один вывод может заключаться в том, что они похожи, но они работают на другом уровне: аппаратные прерывания - это, ну, аппаратное обеспечение, требующее внимания, и программное обеспечение самого низкого уровня. Как правило, ядро обрабатывает все аппаратные средства, а процесс информирования делается несколько независимым от аппаратных прерываний. Для ряда сигналов используется обработка по умолчанию (например, ctrl-z, ctrl-c,...), для других реализация очень зависима от приложения (например, SIGHUP).
Когда дело доходит до сигналов, ну, они просто программно определены. Они делают все, что вы можете им делать, а linux предлагает удобные методы для вызова этих подпрограмм. В некоторых случаях ядро может вызывать сигнальную процедуру (например, SIGSEGV, SIGCHILD,...), но вряд ли когда-либо используется аппаратное обеспечение. Это просто удобный способ запуска конкретной процедуры в приложении.
Раньше был особый случай: прерывание "OS" в DOS 21h. Это больше не используется (хотя все еще работает), но идея такова. Программа может инициировать определенное прерывание, чтобы попросить ядро выполнить определенные действия. Действия - это системные вызовы (открытие файла, закрытие сокета, что у вас есть). Как я уже сказал, интересно, но больше не используется.
Каковы различные источники сигнала? Мне кажется, что ядро всегда является источником сигнала. (Кроме случаев, когда используется для IPC)
Сигнал либо поступает из самого процесса (SIGABRT), из ядра (SIGSEGV,...), либо из других процессов, таких как оболочка, например (ctrl-z, ctrl-c, ctrl- \,...) или от убийства. Но они могут поступать из любой другой программы с помощью функции kill libc:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
Разница между обработчиком сигнала и ISR?.
Основное различие заключается в том, что ISR живут в пространстве ядра и должны учитывать, что весь компьютер заморожен во время их выполнения. Это означает, что они могут прервать любой процесс и что-либо в ядре. Они также "останавливают мир". В то время как прерывание обрабатывается, больше ничего не произойдет. Поэтому, если обработчик прерывания что-то ждет, машина зависает. Если обработчик прерываний переходит в цикл, единственным вариантом является перезагрузка машины.
ISR ДЕЙСТВИТЕЛЬНО трудно получить право. Там много теории на них, на Linux у них есть верхняя половина и нижняя половина разделов, со всеми видами обработки приоритетов, выделение специальной памяти... и это минное поле. Один шаг в неправильном направлении в ISR убьет машину. Ошибка в ISR вызовет dataloss, возможно, даже полный отказ оборудования. Фактически, исходя из опыта, просто возникает подозрение, что вы планируете сделать что-то неправильно в ISR, немедленно приводит к совершенно непредсказуемому поведению машины.
Вы не можете использовать какие-либо средства ядра в ISR. Запустите файл, забудьте об этом. Выделяя память, забудьте ее. Вызывая любую другую часть ядра, забудьте об этом (с несколькими, но только с несколькими исключениями). Список продолжается.
Сигналы - это просто функции в вызываемых вызовах. Сигнал может блокироваться (например, ctrl-z), и это остановит процесс от прогресса, но, например, ваш сеанс оболочки все равно будет реагировать. Процесс должен учитывать, что любая часть программы, возможно, была прервана, конечно, но она по-прежнему является обычным пользовательским пространством. Вы можете блокировать, вы можете зацикливать, вы можете открывать файлы, выделять память,... что хотите.
Разница между блокировкой сигнала и маскированием прерываний?
Они очень похожи. Кроме того, блокировка сигнала выполняется на основе каждого процесса. В обоих случаях есть неблокируемые сигналы, и есть NMI (не маскируемое прерывание) (оба указывают на серьезные ошибки).
В конце сигналы и прерывания отправляют число либо в ядро, либо в определенные процессы. Блокировка сигнала и маскирование прерываний просто означают, что система игнорирует определенные числа.
Одно отличие заключается в том, что маскирование прерываний реализовано в аппаратном обеспечении.
Ответ 3
Сигналы и прерывания ведут себя аналогичным образом. Разница в том, что сигналы происходят с процессом (который живет в виртуальной среде), в то время как исключения являются общесистемными.
Некоторые ошибки отмечены ЦП как исключение, а затем отображаются на сигнал, который передается процессу ядром. Ядро может хотеть скрыть любое исключение из процесса (например, доступ к немаркированной памяти тихо фиксируется пейджингом).
Аппаратные прерывания - это просто своего рода исключение, которое ядро может выбрать для отображения сигнала (например, если вы используете alarm(2)
).
Ядро генерирует сигналы в ответ на различные события, среди которых исключения, завершение ввода-вывода, явные запросы пользовательского пространства,...
Обработчики сигналов ведут себя аналогично ISR - их можно вызвать в любое время, поэтому они не могут делать какие-либо предположения о состоянии программы, как и ISR, - и блокирующие сигналы ведут себя одинаково внутри виртуального адресного пространства, так как маскирующие прерывания выполняются на физической машине.