Главная страница Взаимодействие нетривиальных процессов Пример функции-обертки приведен в листинге 1.1 Листинг 1.1. Функция-обертка к функции sem post I1b/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 в одном операторе, как в нижеследующем примере: Все исходные тексты, опубликованные в этой книге, вы можете найти по адресу http: www.piter.com/ download. int n; if ( (n-pthreacl mutexJock(&ndone mutex))!=0) errno=n. err sys( pthread mutex lock error ): Альтернативой является определение новой функции обработки ошибок, принимающей код ошибки в качестве аргумента. Однако мы можем сделать этот фрагмент кода гораздо более читаемым, записав Pthread mutexJock(&ndone mutex): где используется наша собственная функция-обертка, приведенная в листинге 1.2. Листинг 1.2. Реализация обертки к функции ptliread mutexJock lib/wrappthread.c 125 void 126 Pthread mutex lock(pthread mutex t *mptr) 127 { 128 int n: 129 if ( (n-pthread mutexJock(mptr))-0) 130 return: 131 errno=n: 132 err sys( pthread mutex lock error ); 133 } ПРИМЕЧАНИЕ- Аккуратно используя возможности языка Си, мы могли бы применять макросы вместо функций, что увеличило бы скорость выполнения программ, но эти функции-обертки редко бывают (если вообще бывают) узким местом. Наше соглашение о замене первой буквы имени функции на заглавную является компромиссом. Рассматривалось много других форм записи: использование префикса е ([10, с. 182]), суффикса е и т. д. Наш вариант кажется наименее отвлекающим внимание и одновременно дающим визуааьное указание на то, что вызывается какая-то другая функция. Этот метод имеет побочное полезное свойство; проверяются ошибки, возвращаемые функциями, код возврата которых обычно игнорируется, например close и pthread mutex lock. Далее в тексте книги мы будем использовать эти функции-обертки, если только не потребуется явно проверить наличие ошибки и обработать ее произвольным образом, отличным от завершения процесса. Мы не приводим в книге исходный код для всех оберток, но он свободно доступен в Интернете (см. предисловие). Значение errno При возникновении ошибки в функции Unix глобальной переменной еггпо присваивается положительное значение, указывающее на тип ошибки; при этом функция обычно возвращает значение -1. Наша функция errsys выводит соответствующее коду ошибки сообщение (например, Resource temporarily unavailable - ресурс временно недоступен, - если переменная еггпо имеет значение EAGAIN). Функция присваивает значение переменной еггпо только при возникновении ошибки. В случае нормального завершения работы значение этой переменной не определено. Все положительные значения соответствуют константам с именами из заглавных букв, начинающимися с Е, определяемым обычно в заголовочном файле <sys/errno. h>. Отсутствию ошибок соответствует значение 0. При работе с несколькими потоками в каждом из них должна быть собственная переменная еггпо. Выделение переменной каждому потоку происходит автоматически, однако обычно это требует указания компилятору на то, что должна быть возможность повторного входа в программу. Задается это с помощью ключей -D REENTRANT или -D POSIX C SOURCE=199506L или аналогичных. Часто в заголовке <errno.h> переменная errno определяется как макрос, раскрываемый в вызов функции, если определена константа REENTRANT. Функция обеспечивает доступ к копии errno, относящейся к данному потоку. Далее в тексте мы используем выражения наподобие функция mqsend возвращает 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). Затем выщел стандарт IEEE 1003.1-1990 (356 страниц). Он одновременно являлся и международным стандартом ISO/IEC 9945-1:1990. По сравнению с версией 1988 года изменения в версии 1990 года были минимальными. К заголовку было добавлено: Part 1: System AppUcation Program Interface (API) [C Language]* ( Часть 1: Системный интерфейс разработки программ (API) [Язык С]) , и это означало, что стандарт описывал программный интерфейс (API) языка С.
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |