Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 [ 6 ] 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

Пример функции-обертки приведен в листинге 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) языка С.



1 2 3 4 5 [ 6 ] 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.