UNIX: взаимодействие процессов - страница 8

Шрифт
Интервал

стр.

Все значения semadj в порожденном процессе устанавливаются в 0Все значения semadj передаются новой программеВсе значения semadj добавляются к значению соответствующего семафора
Блокировка записей fcntlБлокировки в родительском процессе не наследуются порожденным процессомБлокировки не изменяются до тех пор, пока не закроется дескрипторВсе несброшенные блокировки, установленные процессом, снимаются
Отображение памятиОтображения памяти родительского процесса сохраняются в порожденномОтображения памяти сбрасываются (unmap)Отображения памяти сбрасываются
Разделяемая память PosixОтображения памяти родительского процесса сохраняются в порожденномОтображения памяти сбрасываютсяОтображения памяти сбрасываются
Разделяемая память System VПрисоединенные сегменты разделяемой памяти остаются присоединенными в порожденном процессеПрисоединенные сегменты разделяемой памяти отсоединяютсяПрисоединенные сегменты разделяемой памяти отсоединяются
Двери (doors)Порожденный процесс получает копии всех открытых дескрипторов родительского процесса, но только родительский процесс является сервером при активизации дверей через дескрипторыВсе дескрипторы дверей должны быть закрыты, потому что они создаются с установленным битом FD_CLOEXECВсе открытые дескрипторы закрываются

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 в одном операторе, как в нижеследующем примере:


стр.

Похожие книги