Прерывания и исключения - PullRequest
       222

Прерывания и исключения

20 голосов
/ 24 сентября 2008

Я видел здесь несколько вопросов о исключениях , и некоторые из них намекают на прерывания как исключения , но ни один из них не проясняет соединение.

  • Что такое прерывание?

  • Что является исключением? (пожалуйста, объясните, какие исключения существуют для каждого языка, который вы знаете, поскольку есть некоторые различия)

  • Когда исключение является прерыванием и наоборот?

Ответы [ 11 ]

19 голосов
/ 24 сентября 2008

Ваш процессор будет иметь несколько внешних контактов прерывания. Как правило, эти контакты подключены к оборудованию и используются для указания, когда происходит какое-то внешнее событие. Например, если вы используете последовательный порт, UART будет поднимать и поднимать вывод, который подключен к одному из выводов прерывания на процессоре, чтобы указать, что байт был получен.

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

Когда процессор получает сигнал на один из своих внешних выводов прерывания, он сразу же переходит в какое-то назначенное место в памяти и начинает выполнение. Выполняемый код обычно называется ISR или подпрограммой обработки прерываний. Если вы не реализуете драйверы или не используете какое-либо встроенное программное обеспечение, маловероятно, что вы когда-нибудь встретите ISR.

К сожалению, ответ на вопрос об исключениях немного менее ясен - в других ответах на этой странице перечислены 3 различных значения.

Ответ Рона Сэвиджа относится к программной конструкции. Это чисто исключение прикладного уровня, где фрагмент кода может указывать на ошибку, которая может быть обнаружена некоторым другим фрагментом кода. Здесь вообще не задействовано оборудование.

Тогда есть исключение, как видно из задачи. Это конструкция уровня операционной системы, которая используется для уничтожения задачи, когда она выполняет что-то недопустимое - например, деление на 0, незаконный доступ к памяти и т. Д.

И, в-третьих, существует аппаратное исключение. С точки зрения поведения это идентично прерыванию в том, что процессор сразу же переместится в какое-то назначенное место в памяти и начнет выполнение. Если исключение отличается от прерывания, это то, что исключение вызвано какой-то незаконной активностью, обнаруженной процессором. Например, MMU на процессоре обнаружит недопустимый доступ к памяти и вызовет исключение. Эти аппаратные исключения являются начальным триггером для операционной системы для выполнения задач очистки (как описано в параграфе выше).

11 голосов
/ 24 сентября 2008

Прерывания генерируются устройствами, внешними по отношению к ЦП (тик таймера, завершение работы диска, прибытие сетевых пакетов и т. Д.), И асинхронны при выполнении программы. Исключения составляют синхронный с выполнением программы (например, деление на ноль, доступ к неверному адресу).

Если ваша программа не выполняется без операционной системы (или вы разрабатываете ОС), она никогда не увидит необработанное исключение / прерывание. Они перехватываются ОС и обрабатываются ею (прерываниями) или преобразуются в какую-либо другую форму перед отражением обратно в пользовательскую программу (например, сигналы в UNIX, структурированная обработка исключений (SEH) в Windows), где есть вероятность обработки это.

9 голосов
/ 24 сентября 2008

Прерывание - это сигнал ЦП, сгенерированный аппаратными средствами или конкретными инструкциями ЦП. Это приводит к выполнению обработчиков прерываний. Такие вещи, как сигналы ввода / вывода от оборудования ввода / вывода, генерируют прерывания.

Исключением можно считать версию программного обеспечения для прерывания, которое влияет только на его процесс.

Я не уверен в точных деталях, но исключение может быть реализовано при прерывании.

8 голосов
/ 24 сентября 2008

Прерывания показывают, что что-то внешнее по отношению к ядру процессора требует его внимания Он прерывает нормальный поток программы, выполняет процедуру обработки прерывания (ISR) и обычно возвращается туда, где он был до того, как произошло прерывание.

Существует много вариантов этой основной темы: программные прерывания могут генерировать прерывания, другая задача может получить ЦП после ISR и т. Д. Ключевым моментом является то, что прерывания могут возникать в любое время по причине кода / Процессор имеет без контроля над .

Исключение немного сложнее определить, потому что оно потенциально имеет три уровня значения:

Аппаратные исключения

Некоторые процессоры (например, PowerPC) определяют исключения, чтобы указать, что произошло какое-то необычное состояние: сброс системы, неверный адрес, некоторые ошибки в кэше преобразования виртуальных адресов и т. Д. ...

Эти исключения также используются для реализации точек останова и системных вызовов. В этом случае они действуют почти как прерывания.

ОС исключения

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

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

Я бы рассматривал структурированные обработчики исключений окна (SEH) как исключения этого типа.

Программные исключения

Некоторые языки, такие как Java, C ++ и C #, имеют концепцию программных исключений, где язык обеспечивает обработку непредвиденных или необычных условий , связанных с работой программы . В этом случае в какой-то момент кода возникает исключение, и некоторый код, находящийся выше в стеке выполнения программы, может «перехватить» исключение и выполнить. Это то, что делают блоки try / catch.

5 голосов
/ 24 сентября 2008

Исключение

Исключение составляют случаи, когда процессор выполняет код, который находится не по его обычному пути. Это «исключение» для нормальной работы, которая, по сути, представляет собой линейное движение через код и управляющие структуры. Различные языки поддерживают различные типы исключений, обычно используемые для обработки ошибок во время работы программы.

Прерывание

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

Прерывание всегда является исключением, даже если оно предназначено. Прерывания могут указывать:

  • ошибки, такие как нарушение доступа к памяти
  • что ОС должна выполнить операцию для поддержки работающей программы, такую ​​как программное прерывание или запрос на подкачку памяти
  • аппаратное устройство требует внимания, например, принятый сетевой пакет или пустой буфер передачи

Это всегда вынуждает процессор приостанавливать свою текущую активность для обработки возникшего исключения, возобновляя работу только после завершения обработки прерывания.

Ловушки

С точки зрения прерываний, распространенными ловушками являются условия гонки. Например, у вас может быть прерывание, которое периодически увеличивает глобальные часы реального времени. Часы могут быть 64-битными на 32-битной машине.

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

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

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

-Adam

5 голосов
/ 24 сентября 2008

Я собираюсь пояснить, что такое прерывание, потому что есть один критический тип прерывания, с которым еще никто не имел дело: таймер.

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

В каждый момент времени на процессоре запускается только один процесс. И когда вы используете многозадачную ОС, способ переключения между ними называется переключением контекста - в основном регистры процессора сбрасываются в память, поток переходит к новому процессу, а когда процесс завершается, вы переключаете контекст на что-то другое. еще.

Итак, допустим, я пишу простую программу на C, которая считает все числа, или последовательность Фибоначчи, или что-то еще без остановки. Или даже лучше: ничего не делает, только вращается внутри цикла while (1). Как другие процессы в системе получают возможность запуска? Что если ничего не происходит, что вызывает прерывание?

Ответ в том, что у вас есть устройство таймера, которое постоянно прерывает работу. И это то, что удерживает процесс вращения от разрушения всей системы. Хотя я отмечу, что обработчики прерываний отключают прерывания, поэтому, если вы делаете что-то, что блокирует на неопределенный срок, вы можете отключить всю систему.

4 голосов
/ 24 сентября 2008

Прерывания, как ожидается, будут происходить регулярно (хотя иногда они не регулярны) .. они прерывают процессор, потому что что-то важное только что произошло и о нем нужно немедленно позаботиться.

Исключения должны быть исключениями к правилу; они выбрасываются программным обеспечением, потому что произошло нечто неожиданное, и это ваш шанс попытаться что-то с этим сделать или, по крайней мере, грациозно потерпеть крах.

2 голосов
/ 24 сентября 2008

Простые вещи ...

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

Обработка исключения включает отбрасывание последовательных слоев того, над чем вы сейчас работаете, до тех пор, пока вы не всплывет до точки, где исключение может быть обработано (перехвачено).

Во время обработки прерывания вы можете решить выдать исключение, но это не значит, что вы должны рассматривать само прерывание как исключение. Исключения не «прерывают» (поскольку это подразумевает возможность возврата к тому, что вы делали непосредственно перед тем, как вас прервали); скорее они "прерывают" (некоторое подмножество) вашу текущую активность.

И, как уже отмечалось несколько раз, прерывания обычно инициируются внешними объектами, такими как оборудование или пользователи (например, щелчок мыши или нажатие клавиши, например CTRL-C), в то время как исключения генерируются (генерируются) синхронно с помощью программного обеспечения, обнаруживающего «проблему» "или" исключительное состояние ".

2 голосов
/ 24 сентября 2008

Iterrupts в основном аппаратно-управляемый, например, ваш принтер указывает, что на нем нет бумаги, или сетевая карта указывает, что он потерял соединение.

Исключением является просто состояние ошибки в вашей программе, обнаруженное блоком try / catch. Как:

Try
   {
   ... various code steps that "throw exceptions" on error ...
   }
catch (exception e)
   {
   print 'Crap! Something bad happened.' + e.toString()
   }

Это удобный способ отловить «любую ошибку», которая происходит в блоке кода, чтобы вы могли обрабатывать их аналогичным образом.

2 голосов
/ 24 сентября 2008

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

Исключением является программно реализованный способ обработки ошибок в коде. Вы устанавливаете обработчик для определенных (или общих) исключений. Когда возникает исключение, языки выполнения начнут разматывать стек, пока не достигнут обработчик для этого конкретного обработчика. В этот момент вы можете обработать исключение и продолжить или выйти из программы.

...