ДС18в13-исключения (1238914)
Текст из файла
Исключения и процессыОсновы информатики.Компьютерные основы программированияgoo.gl/X7evFНа основе CMU 15-213/18-243:Introduction to Computer Systemsgoo.gl/TDDVVЛекция 13, 30 апреля, 2018Лектор:Дмитрий Северов, кафедра информатики 608 КПМdseverov@mail.mipt.rucs.mipt.ru/wp/?page_id=3461Исключения и процессы¢¢¢¢Поток управления с исключениямиИсключенияПроцессыУправление процессами2Поток управления¢Процессор занят только одним:§ От запуска до останова, ЦП просто читает и исполняет(интерпретирует) последовательность команд, одну за раз.§ Эта последовательность – поток управления ЦПФизический поток управленияВремя<запуск>команда1команда2команда3…командаn<останов>3Изменение потока управления¢До сих пор: два механизма изменения потока управления:§ Безусловный и условные переходы§ Обращение к процедуре и возврат из процедурыОба реагируют на изменения в состоянии программы¢Недостаточно для практической системы:Трудно реагировать на изменения в состоянии системы§§§§¢данные поступают с диска и/или из сетикоманды делят на нольпользователь нажимает Ctrl-C на клавиатуресрабатывают системные таймерыНужны механизмы “потока управления с исключениями”4Поток управления с исключениями(исключительными ситуациями)¢¢Присутствует на всех уровнях компьютерной системыНизкоуровневые механизмы1.
Исключения§§¢изменения в потоке управления в ответ на события в системе(т.е., на изменение состояния системы)Комбинация аппаратуры и ПО операционной системыВысокоуровневые механизмы2. Смена контекстов (вычислительных) процессовПО операционной системы и аппаратный таймер3. Сигналы§ ПО операционной системы4. Нелокальные переходы : setjmp() и longjmp()§ Реализуются средой исполнения языка С§5Исключения и процессы¢¢¢¢Поток управления с исключениямиИсключенияПроцессыУправление процессами6Исключения (исключительные ситуации)¢Исключение – передача управления операционной системе вответ на некоторое событие (т.е., изменение состояния ЦП)Процесс пользователясобытиек_текущаяк_следующаяОСисключение• возврат к к_текущая• возврат к к_следующая• прекращение¢обработка исключенияспециальной программойПримеры:деление на 0, арифметическое переполнение, ошибочная страница памяти,завершение в/в, Ctrl-C7Вектора прерыванийНомерисключениякод обработчикаисключения 0Таблицаисключений012n-1...код обработчикаисключения 1¢¢код обработчикаисключения 2...¢Каждый тип событий имеетуникальный номер исключения kk = индекс в таблице исключений(т.н.
вектор прерывания)Обработчик k вызывается всякийраз, как возникает исключение kкод обработчикаисключения n-18Асинхронные исключения (прерывания)¢Вызываются внешними для процессора событиями§ Обозначается установкой напряжения на специальном контакте ЦП§ Обработчик возвращается к “следующей” команде¢Примеры:§ Прерывание таймераКаждые несколько мс аппаратура таймера делает прерывание§ Используется ядром ОС для отъёма управления у других программ§ Ввод/вывод§ нажатие Ctrl-C на клавиатуре§ поступление пакета данных из сети§ поступление блока данных с диска§9Синхронные исключения¢Возникают в результате исполнения команд:§ Ловушки (Traps)преднамеренные§ примеры: обращения к ядру ОС, точки останова, спецкоманды§ возвращают управление на “следующую” команду§ Сбои (Faults)§ непреднамеренные и возможно исправимые§ примеры: сбой обращения к странице виртуальной памяти(исправима), нарушение защиты виртуальной памяти (неисправима),исключение вычислений с плавающей точкой§ либо повторно исполняет сбойную (“текущую”) команду иливызывает прекращение работы программы§ Прекращения (Aborts)§ непреднамеренные и неисправимые§ примеры: ошибка чётности памяти, самодиагностика аппаратуры,недопустимая команда§ прекращает текущую программу10§Примеры исключений x86-64Номер исключенияОписаниеКласс исключения0Деление на 0Сбой13Сбой общей защитыСбой14Страничный сбойСбой18Самопроверка машины Прекращение32-255Исключения,определяемые ОСПрерывания, ловушки11Вызовы системы¢¢Каждое вызов x86-64 системы имеет уникальный номерПримеры:НомерИмяОписание0readПрочитать файл1writeЗаписать файл2openОткрыть файл3closeЗакрыть файл4statПолучить информацию о файле57forkСоздать процесс59execveВыполнить программу60_exitЗавершить процесс62killОтправить сигнал процессу12Вызов системы (ловушка): открыть файл¢¢В С-программе вызвается: open(filename, options)Вызывает функцию __open с командой системного вызова syscall00000000000e5d70 <__open>:...e5d79:b8 02 00 00 00e5d7e:0f 05e5d80:48 3d 01 f0 ff ff...e5dfa:c3Код программыsyscallcmpmov $0x2,%eax # open - сисвызов №2syscall# Результат - в %raxcmp $0xfffffffffffff001,%raxretqКод ядра ОС¢¢ИсключениеOpen fileВозврат¢¢в %rax – номер вызовав %rdi, %rsi, %rdx, %r10,%r8, %r9 – другие аргументыРезультат в %raxОтрицательное значение –ошибка, соответсвующаяяотрицательному errno13Сбой страницы [виртуальной памяти]¢¢int a[1000];main (){a[500] = 13;}Пользователь пишет в памятьНужная часть (страница) пользовательскойпамяти в этот момент откачана на диск80483b7:c7 05 10 9d 04 08 0dПроцесс пользователяmovlmovl$0xd,0x8049d10ОСИсключение: сбойстраницы ВПСтраница памятиподкачивается с дискаВозврат и повторноевыполнение movl¢¢¢Обработчик сбоя страницы загружает страницу в физическую памятьВозвращает управление на сбойную командуСбойная команда успешно выполняется со второй попытки14Пример прекращения: негодный адрес(Invalid Memory Reference)int a[1000];main (){a[5000] = 13;}80483b7:c7 05 60 e3 04 08 0dПроцесс пользователяmovl¢¢исключениеmovl$0xd,0x804e360OSобнаружениенегодного адресасигналпроцессуОтправляет сигнал SIGSEGV процессу пользователяПроцесс пользователя завершается с сообщением “segmentation fault”15Исключения и процессы¢¢¢¢Поток управления с исключениямиИсключенияПроцессыУправление процессами16Процессы¢Определение: процесс – экземпляр исполненияпрограммы§ Одна из фундаментальных концепций в информатике§ Совсем не тоже самое, что “программа” или “процессор”¢Процесс реализует каждой программе двеключевые абстракции (иллюзии) :§ Логический поток управленияКаждой программе видится монопольное владение ЦП§ Реализуется в ядре ОС механизмомпереключения контекста§ Частное виртуальное адресное пространство§ Каждой программе видится монопольное владениепамятью§ Реализуется в ядре ОС механизмомвиртуальной памяти§ПамятьСтекКучаДанныеИсп.кодЦПРегистры17Иллюзия многопроцессности¢ПамятьПамятьПамятьСтекКучаДанныеИсп.кодСтекКучаДанныеИсп.кодСтекКучаДанныеИсп.кодЦПЦПЦПРегистрыРегистрыРегистры…Компьютер исполняет несколько процессов одновременно§ Приложения для одного и более пользователейВеб-обозреватели, почтовые клиенты, редакторы, …§ Фоновые задачи§ Наблюдение за сетью и прочими устройствами ввода-вывода§18Пример многопроцессности¢Исполнение программы “top” на Mac§ В системе 123 процесса, 5 из которых активны§ Различаются по идентификатору процесса (PID)19Реальность многопроцессности (раньше)ПамятьСтекКучаДанныеКодСтекКучаДанныеКодХранимыерегистрыХранимыерегистры…СтекКучаДанныеКодХранимыерегистрыЦПРегистры¢Один процессор исполняет несколько процессов параллельно§ Перекрывающиеся во времени выполнения процессов (многозадачность)§ Адресные пространства управляются виртуальной памятью§ Содержимое значений регистров неисполняемых процессов сохраняется в памяти20Реальность многопроцессности (раньше)ПамятьСтекКучаДанныеКодСтекКучаДанныеКодХранимыерегистрыХранимыерегистры…СтекКучаДанныеКодХранимыерегистрыЦПРегистры¢Текущее содержимое текущих регистров – в память21Реальность многопроцессности (раньше)ПамятьСтекКучаДанныеКодСтекКучаДанныеКодХранимыерегистрыХранимыерегистры…СтекКучаДанныеКодХранимыерегистрыЦПРегистры¢Выбрать следующий процесс для выполнения22Реальность многопроцессности (раньше)ПамятьСтекКучаДанныеКодСтекКучаДанныеКодХранимыерегистрыХранимыерегистры…СтекКучаДанныеКодХранимыерегистрыЦПРегистры¢Загрузить сохранённые регистры и переключить адресноепространство (переключить контекст)23Реальность многопроцессности (сейчас)ПамятьСтекКучаДанныеКодСтекКучаДанныеКодХранимыерегистрыХранимыерегистрыЦПЦПРегистрыРегистры…СтекКучаДанныеКодХранимыерегистры¢Многоядерные процессоры§ Несколько ЦП на одном кристалле§ Общие основная память и некоторыекеши§ Каждый исполняет свой процесс§ ядро ОС распределяет процессыпо ядрам кристалла24Одновременные процессы¢¢¢Два процесса идут одновременнo (являютсяодновременными) если каждый из процессов начинаетсядо завершения другогоВ противном случае, они являются последовательнымиПримеры (исполнение на единственном ядре ЦП):§ Одновременные: A & B, A & C§ Последовательные: B & CПроцесс AПроцесс BПроцесс CВремя25Точка зрения пользователяна одновременные процессы¢¢Потоки управления одновременных процессовфизически разнесены во времениПри этом, мы можем мыслить одновременныепроцессы идущими параллельно друг с другомПроцесс AПроцесс BПроцесс CВремя26Смена контекста процессов¢Процессы управляются частью исполняемого кода ОС,под названием ядро ОС (kernel)§ Важно: ядро ОС не отдельный процесс, но выполняется в паузахнекоторых пользовательских процессов¢Физический поток управления переходит от одногопроцесса к другому посредством смены контекстаПроцесс AПроцесс Bкод пользователякод ядра ОСВремясмена контекстакод пользователякод ядра ОСсмена контекстакод пользователя27Исключения и процессы¢¢¢¢Поток управления с исключениямиИсключенияПроцессыУправление процессами28Обработка ошибок вызова системы¢¢Если ошибка, то функции системного уровня Unix обычновозвращают -1 и устанавливают глобальнуюпеременную errno для обозначения причины.Тяжелое но быстрое правило:§ Вы обязаны проверять результат каждого вызова функцийсистемного уровня§ Исключение – немногие функции, типа void¢if ((pidExample:= fork()) < 0) {fprintf(stderr, "fork error: %s\n", strerror(errno));exit(0);}29Функции сообщений об ошибках¢Проще использовать функции сообщений об ошибках:void unix_error(char *msg) /* Ошибки в стиле Unix */{fprintf(stderr, "%s: %s\n", msg, strerror(errno));exit(0);}if ((pid = fork()) < 0)unix_error("fork error");30Обертки обработки ошибок¢Ещё упростим демонстрируемый код обёртками вдругом стиле:pid_t Fork(void){pid_t pid;if ((pid = fork()) < 0)unix_error("Fork error");return pid;}pid = Fork();31Запрос идентификатора процесса (PID)¢pid_t getpid(void)§ Возвращает PID текущего процесса¢pid_t getppid(void)§ Возвращает PID родительского процесса32Создание и завершение процессовПрограммист мыслит о 3 возможных состоянияхпроцесса¢Исполняется§ Процесс или исполняется, или ожидает исполнения и будетвыбран ядром ОС для исполнения¢Остановлен§ Исполнение процесса отложено, и не будет возобновляться доспециального сигнала¢Завершён§ Процесс необратимо прекращён33Завершение процесса¢Процесс завершается по 1 из 3 причин:§ Получает сигнал, по которому должен завершиться§ Возвращает управление из программы main§ Вызывает функцию exit¢void exit(int status)§ Завершает процесс с кодом завершения status§ Соглашение: код нормального завершения 0, не 0 – при ошибке§ Другой способ явно указать код завершения вернуть целоезначение из программы main¢exit вызывается однажды и никогда не возвращает34Создание процессов¢¢Родительский процесс создаёт новый дочерний процессобращением к forkint fork(void)§ Возвращает 0 дочернему процессу, и PID дочернего - родительскому§ Дочерний почти идентичен родительскому:§§§¢Дочерний получает идентичную (но отдельную) копиюродительского виртуального адресного пространства.Дочерний получает идентичные копии описаний файловоткрытых родительскимДочерний получает PID, иной чем у родителяfork привлекает (и часто запутывает) потому, чтовызыванный однажды возвращает дважды35Пример вызова fork¢int main(){pid_t pid;int x = 1;¢§ Нельзя предсказать порядокpid = Fork();if (pid == 0) { /* Потомок */printf("child : x=%d\n", ++x);exit(0);}выполнения родителя ипотомка¢возвращает и родителю ипотомку§ последующие изменения xнезависимыfork.clinux> ./forkparent: x=0child : x=2Отдельная копия адресногопространства§ x равен 1, когда fork/* Родитель */printf("parent: x=%d\n", --x);exit(0);}На 1 вызов, 2 возвратаОдновременная работа¢Вместе используют файлы§ stdout одинаков и вродителе и в потомке36Моделирование fork графом процессов¢Граф процессов – удобное средство понимания честивнойупорядоченности операторов в параллельной программе:§§§§§¢Каждая вершина – исполнение оператораa -> b означает, что a произошло раньше bРебра помечаются текущими значениями переменныхВершины printf помечаются выводимым текстомКаждый граф начинается вершиной без входящих рёберЛюбая топологическая сортировка графа соответствуетвозможному полному порядку.§ Полный порядок вершин, при котором все ребра указывают слеванаправо37Пример графа процессовint main(){pid_t pid;int x = 1;Потомокpid = Fork();if (pid == 0) { /* Потомок */printf("child : x=%d\n", ++x);exit(0);}child: x=2printfexitparent: x=0 Родительx==1mainforkprintfexit/* Родитель */printf("parent: x=%d\n", --x);exit(0);}fork.c38Интерпретация графа процессов¢Исходный граф:child: x=2printfparent: x=0x==1main¢exitforkprintfexitВозможный порядок:Переразмеченный graph:abefcdabecfdНевозможный порядок:abfced392 последовательных fork-аByevoid fork2(){printf("L0\n");fork();printf("L1\n");fork();printf("Bye\n");}forks.cprintfL1printfByeforkprintfByeprintfprintfByeL1L0forkprintfВозможный вывод:L0L1ByeByeL1ByeByeforkprintfНевозможный вывод:L0ByeL1ByeL1ByeBye40Вложенные fork-и в родителеvoid fork4(){printf("L0\n");ByeByeif (fork() != 0) {printfprintfprintf("L1\n");L0L1L2Byeif (fork() != 0) {printf fork printf fork printf printfprintf("L2\n");}}printf("Bye\n");Возможный вывод:Невозможный вывод:}forks.cL0L0L1ByeByeL1ByeByeL2ByeByeL241Вложенные fork-и в потомкеvoid fork5(){printf("L0\n");if (fork() == 0) {printf("L1\n");if (fork() == 0) {printf("L2\n");}}printf("Bye\n");}forks.cL2Byeprintf printfL1printfByeL0printfforkforkByeprintfprintfВозможный вывод:L0ByeL1L2ByeByeНевозможный вывод:L0ByeL1ByeByeL242Скашивание дочерних процессов¢Идея§ Когда процесс завершён, он всё ещё потребляет ресурсы ОСРазличные системные таблицы§ Называется “зомби”§ Живой труп, полуживой полумёртвый§¢Скашивание (reaping)§ Выполняется родительским процессом над завершённым дочерним§ Родительский процесс получает статус завершения дочернего§ Ядро ОС очищает системные таблицы от данных дочернего процесса¢Что если родительский процесс не скосит дочерний?§ если родительский завершится не срезав дочерние, то дочерниебудут срезаны процессом–прародителем init§ явное срезание необходимо долгоживущим процессам§ например оболочкам и серверам43Зомбиvoid fork7() {if (fork() == 0) {/* Потомок */printf("Terminating Child, PID = %d\n", getpid());exit(0);} else {printf("Running Parent, PID = %d\n", getpid());while (1); /* Бесконечный цикл */}forks.c}linux> ./forks 7 &[1] 6639Running Parent, PID = 6639Terminating Child, PID = 6640linux> psPID TTYTIME CMD6585 ttyp900:00:00 tcsh6639 ttyp900:00:03 forks6640 ttyp900:00:00 forks <defunct>6641 ttyp900:00:00 pslinux> kill 6639[1]Terminatedlinux> psPID TTYTIME CMD6585 ttyp900:00:00 tcsh6642 ttyp900:00:00 ps¢¢ps показывает потомка“defunct” (например, зомби)Кончина родителя позволяетinit-у скосить потомка44Бесконечныйпотомокvoid fork8(){if (fork() == 0) {/* Потомок */printf("Running Child, PID = %d\n",getpid());while (1); /* Бесконечный цикл */} else {printf("Terminating Parent, PID = %d\n",getpid());exit(0);}}forks.clinux> ./forks 8Terminating Parent, PID = 6675Running Child, PID = 6676linux> psPID TTYTIME CMD6585 ttyp900:00:00 tcsh6676 ttyp900:00:06 forks6677 ttyp900:00:00 pslinux> kill 6676linux> psPID TTYTIME CMD6585 ttyp900:00:00 tcsh6678 ttyp900:00:00 ps¢¢Потомок активен, несмотря накончину родителяНеобходимо кончить потомкаявно, или он будет выполнятьсябез конца.45wait: синхронизация с потомком¢Родитель скашивает потомка вызовом функции wait¢int wait(int *child_status)§ Останавливает текущий процесс до кончины одного из потомков§ Возвращает pid законченного потомка§ Если child_status != NULL, то он указывает на значениепричины и статус завершения:§ Проверять можно макросами из wait.h– WIFEXITED, WEXITSTATIS, WIFSIGNALED,WTERMSIG, WIFSTOPPED, WSTOPSIG,WIFCONTINUED– Детали в книге46wait: синхронизация с потомкомvoid fork9() {int child_status;if (fork() == 0) {printf("HC: hello from child\n");exit(0);} else {printf("HP: hello from parent\n");wait(&child_status);printf("CT: child has terminated\n");}printf("Bye\n");}HCprintfHPfork printfexitCTByewait printfforks.cВозможный вывод:HCHPCTByeНевозможный вывод:HPCTByeHC47Ещё wait¢¢Несколько потомков кончаются в произвольном порядкеДля получения информации о статусах завершения полезны макросыWIFEXITED и WEXITSTATUSvoid fork10() {pid_t pid[N];int i, child_status;for (i = 0; i < N; i++)if ((pid[i] = fork()) == 0) {exit(100+i); /* Потомок */}for (i = 0; i < N; i++) { /* Родитель */pid_t wpid = wait(&child_status);if (WIFEXITED(child_status))printf("Child %d terminated with exit status %d\n",wpid, WEXITSTATUS(child_status));elseprintf("Child %d terminate abnormally\n", wpid);}}forks.c48waitpid: ожидание определённого процессаpid_t waitpid(pid_t pid, int &status, int options)§ Останавливает текущий процесс до кончины указанного§ Варианты смотрите в книге§ fork11()Various options(see textbook)void{¢pid_t pid[N];int i;int child_status;for (i = 0; i < N; i++)if ((pid[i] = fork()) == 0)exit(100+i); /* Child */for (i = N-1; i >= 0; i--) {pid_t wpid = waitpid(pid[i], &child_status, 0);if (WIFEXITED(child_status))printf("Child %d terminated with exit status %d\n",wpid, WEXITSTATUS(child_status));elseprintf("Child %d terminate abnormally\n", wpid);}}forks.c49execve: загрузка и запуск программ¢int execve(char *filename, char *argv[], char *envp[])¢Загружает и запускает в текущем процессе:§ Исполняемый файл filenameМожет быть загружаемым файлом или сценарием начинающимся с#!interpreter(например, #!/bin/bash)§ …со списком аргументов argv§ По соглашению argv[0]==filename§ …and списком переменных окружения envp§ Строки “имя=значений” (например, USER=droh)§ getenv, putenv, printenv§¢Перезаписывает code, data и stack§ Сохраняет PID, открытые файлы и контекст сигналов context¢Однажды вызванная никогда не возвращает, т.к.
Характеристики
Тип файла PDF
PDF-формат наиболее широко используется для просмотра любого типа файлов на любом устройстве. В него можно сохранить документ, таблицы, презентацию, текст, чертежи, вычисления, графики и всё остальное, что можно показать на экране любого устройства. Именно его лучше всего использовать для печати.
Например, если Вам нужно распечатать чертёж из автокада, Вы сохраните чертёж на флешку, но будет ли автокад в пункте печати? А если будет, то нужная версия с нужными библиотеками? Именно для этого и нужен формат PDF - в нём точно будет показано верно вне зависимости от того, в какой программе создали PDF-файл и есть ли нужная программа для его просмотра.