Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

Стивенс Уильям Ричард

Шрифт:

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 }

Если в тексте вы встретите имя функции, начинающееся с заглавной буквы, знайте: это наша собственная функция-обертка. Она вызывает функцию с тем же именем, начинающимся со строчной буквы. Функция-обертка приводит к завершению работы процесса с выводом сообщения об ошибке, если таковая возникает.

1

Все исходные тексты, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com/download.

При описании исходного кода, включенного в книгу, мы всегда говорим о вызываемой функции самого низкого уровня (например, 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 прошли несколько стадий разработки.

  • Читать дальше
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • ...

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

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: