- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания UNIX: взаимодействие процессов - Уильям Стивенс
Шрифт:
Интервал:
Закладка:
1.6. Обработка ошибок: функции-обертки
В любой реальной программе при любом вызове требуется проверка возвращаемого значения на наличие ошибки. Поскольку обычно работа программ при возникновении ошибок завершается, мы можем сократить объем текста, определив функции-обертки (wrapper functions), которые осуществляют собственно вызов функции, проверяют возвращаемое значение и завершают работу при возникновении ошибок. В соответствии с соглашениями имена функций-оберток совпадают с именами самих функций, за исключением первой буквы, которая делается заглавной, например
Sem_post(ptr);
Пример функции-обертки приведен в листинге 1.1[1]
Листинг 1.1. Функция-обертка к функции sem_post// lib/wrapunix.c
387 void
388 Sem_post(sem_t *sem)
389 {
390 if (sem_post(sem) == –1)
391 err_sys("sem_post error");
392 }
Если в тексте вы встретите имя функции, начинающееся с заглавной буквы, знайте: это наша собственная функция-обертка. Она вызывает функцию с тем же именем, начинающимся со строчной буквы. Функция-обертка приводит к завершению работы процесса с выводом сообщения об ошибке, если таковая возникает.
При описании исходного кода, включенного в книгу, мы всегда говорим о вызываемой функции самого низкого уровня (например, sem_post), а не о функции-обертке (например, Sem_post). Аналогично в алфавитном указателе приведены имена самих функций, а не оберток к ним.
ПРИМЕЧАНИЕ
Вышеприведенный формат исходного кода используется во всем тексте. Все непустые строки нумеруются. Текст, описывающий разделы кода, начинается с номеров первой и последней строк на пустом поле слева. Иногда перед абзацем текста присутствует краткий заголовок, набранный полужирным шрифтом, излагающий основное содержание описываемого кода.
В начале кода указывается имя исходного файла. В данном примере — это файл wrapunix.c в каталоге lib. Поскольку исходный код всех примеров этой книги распространяется свободно (см. предисловие), вы можете легко найти требуемый файл. Компиляция, выполнение и особенно изменение этих программ в процессе чтения книги — лучший способ изучить концепции взаимодействия процессов.
Хотя может показаться, что использовать такие функции-обертки не слишком выгодно, вы избавитесь от этого заблуждения в главе 7, где мы обнаружим, что функции для работы с потоками (thread functions) не присваивают значение стандартной переменной Unix errno при возникновении ошибки; вместо этого код ошибки просто возвращается функцией. Это означает, что при вызове функции pthread мы должны каждый раз выделять память под переменную, сохранять в ней возвращаемое функцией значение, а затем устанавливать значение переменной errno равным этой переменной, прежде чем вызывать функцию err_sys (листинг В.4). Чтобы не загромождать текст фигурными скобками, мы используем оператор языка Си «запятая» (comma) и совмещаем присваивание значения переменной errno и вызов err_sys в одном операторе, как в нижеследующем примере:
int n;
if ((n = pthread_mutex_lock(&ndone_mutex))!=0) errno=n, err_sys("pthread_mutex_lock error");
Альтернативой является определение новой функции обработки ошибок, принимающей код ошибки в качестве аргумента. Однако мы можем сделать этот фрагмент кода гораздо более читаемым, записав
Pthread_mutex_lock(&ndone_mutex);
где используется наша собственная функция-обертка, приведенная в листинге 1.2.
Листинг 1.2. Реализация обертки к функции pthread_mutex_lock//lib/wrappthread.c
125 void
126 Pthread_mutex_lock(pthread_mutex_t *mptr)
127 {
128 int n;
129 if ((n=pthread_mutex_lock(mptr))==0)
130 return;
131 errno=n;
132 err_sys("pthread_mutex_lock error");
133 }
ПРИМЕЧАНИЕ
Аккуратно используя возможности языка Си, мы могли бы применять макросы вместо функций, что увеличило бы скорость выполнения программ, но эти функции-обертки редко бывают (если вообще бывают) узким местом.
Наше соглашение о замене первой буквы имени функции на заглавную является компромиссом. Рассматривалось много других форм записи: использование префикса е ([10, с. 182]), суффикса _е и т. д. Наш вариант кажется наименее отвлекающим внимание и одновременно дающим визуальное указание на то, что вызывается какая-то другая функция.
Этот метод имеет побочное полезное свойство: проверяются ошибки, возвращаемые функциями, код возврата которых обычно игнорируется, например close и pthread_ mutex_lock.
Далее в тексте книги мы будем использовать эти функции-обертки, если только не потребуется явно проверить наличие ошибки и обработать ее произвольным образом, отличным от завершения процесса. Мы не приводим в книге исходный код для всех оберток, но он свободно доступен в Интернете (см. предисловие).
Значение errno
При возникновении ошибки в функции Unix глобальной переменной errno присваивается положительное значение, указывающее на тип ошибки; при этом функция обычно возвращает значение –1. Наша функция err_sys выводит соответствующее коду ошибки сообщение (например, Resource temporarily unavailable — ресурс временно недоступен, — если переменная errno имеет значение EAGAIN).
Функция присваивает значение переменной errno только при возникновении ошибки. В случае нормального завершения работы значение этой переменной не определено. Все положительные значения соответствуют константам с именами из заглавных букв, начинающимися с Е, определяемым обычно в заголовочном файле <sys/errno.h>. Отсутствию ошибок соответствует значение 0.
При работе с несколькими потоками в каждом из них должна быть собственная переменная errno. Выделение переменной каждому потоку происходит автоматически, однако обычно это требует указания компилятору на то, что должна быть возможность повторного входа в программу. Задается это с помощью ключей –D_REENTRANT или –D_POSIX_C_SOURCE=199506L или аналогичных. Часто в заголовке <errno.h> переменная errno определяется как макрос, раскрываемый в вызов функции, если определена константа _REENTRANT. Функция обеспечивает доступ к копии errno, относящейся к данному потоку.
Далее в тексте мы используем выражения наподобие «функция mq_send возвращает EMSGSIZE», означающие, что функция возвращает ошибку (обычно возвращаемое значение при этом равно –1) и присваивает переменной errno значение указанной константы.
1.7. Стандарты Unix
В настоящее время стандарты Unix определяются Posix и The Open Group.
Posix
Название Posix образовано от «Portable Operating System Interface», что означает приблизительно «интерфейс переносимых операционных систем». Это не один стандарт, а целое семейство, разработанное Институтом инженеров по электротехнике и радиоэлектронике (Institute for Electrical and Electronics Engineers — IEEE). Стандарты Posix были также приняты в качестве международных стандартов ISO (International Organization for Standardization, Международная организация по стандартизации) и IEC (International Electrotechnical Commission, Международная электротехническая комиссия), или ISO/IEC. Стандарты Posix прошли несколько стадий разработки.
■ Стандарт IEEE 1003.1-1988 (317 страниц) был первым стандартом Posix. Он определял интерфейс взаимодействия языка С с ядром Unix-типа в следующих областях: примитивы для реализации процессов (вызовы fork, exec, сигналы и таймеры), среда процесса (идентификаторы пользователей, группы процессов), файлы и каталоги (все функции ввода-вывода), работа с терминалом, базы данных системы (файлы паролей и групп), форматы архивов tar и cpio.
ПРИМЕЧАНИЕ
Первый стандарт Posix вышел в рабочем варианте под названием IEEEIX в 1986 году. Название Posix было предложено Ричардом Штолманом (Richard Stallman).
■ Затем вышел стандарт IEЕЕ 1003.1-1990 (356 страниц). Он одновременно являлся и международным стандартом ISO/IEC 9945-1:1990. По сравнению с версией 1988 года изменения в версии 1990 года были минимальными. К заголовку было добавлено: «Part 1: System Application Program Interface (API) [C Language]» («Часть 1: Системный интерфейс разработки программ (API) [Язык С])», и это означало, что стандарт описывал программный интерфейс (API) языка С.
■ IEEE 1003.2-1992 вышел в двух томах общим объемом около 1300 страниц, и его заголовок содержал строку «Part 2: Shell and Utilities» (Часть 2: «Интерпретатор и утилиты»). Эта часть определяла интерпретатор (основанный на Bourne shell в Unix System V) и около ста утилит (программ, обычно вызываемых из интерпретатора — от awk и basename до vi и уасс). В настоящей книге мы будем ссылаться на этот стандарт под именем Posix. 2.
■ IEEE 1003.1b-1993 (590 страниц) изначально был известен как IEEE P1003.4. Этот стандарт представлял собой дополнение к стандарту 1003.1-1990 и включал расширения реального времени, разработанные рабочей группой Р1003.4: синхронизацию файлов, асинхронный ввод-вывод, семафоры, управление памятью, планирование выполнения (scheduling), часы, таймеры и очереди сообщений.