Операционная система UNIX. Руководство программиста




Получение информации о блокировке - часть 2


Функция lockf(3C) с операцией F_TEST также может быть использована для выявления процесса, мешающего установить блокировку. Однако эта функция не способна определить заблокированный участок сегмента и то, какой процесс заблокировал его. Программа, использующая lockf(3C) для проверки факта блокировки файла, приведена ниже:

/* Выявление заблокированного сегмента */

/* Установка на начало файла */ (void) lseek (fd, 0, 0L);

/* Нулевой размер тестируемого сегмента означает проверку до конца файла */ if (lockf (fd, F_TEST, 0L) < 0) { switch (errno) { case EACCES: case EAGAIN: (void) printf ("Файл блокирован другим процессом\n"); break; case EBADF: /* Некорректные аргументы lockf */ perror ("lockf"); break; default: (void) printf ( "lockf: непредусмотренная ошибка <%d>\n",errno); break; } }

Процесс, порожденный в результате выполнения системного вызова fork(2), наследует копии дескрипторов файлов, открытых процессом-предком. Кроме того, порождающий и порожденный процессы (для каждого файла) разделяют общий указатель текущей позиции в файле. Если процесс-предок изменит указатель файла, то изменение затронет и порожденный процесс. Такое положение влечет важные следствия при использовании блокировки сегментов. Если значение поля l_whence равно 1, то l_start указывает смещение начала блокируемого сегмента относительно указателя текущей позиции в файле. Если и порождающий, и порожденный процессы блокируют сегменты одного и того же файла, то существует вероятность, что при этом будет использоваться указатель текущей позиции, измененный другим процессом. Эта проблема существует и в случае использования функции lockf(3C) и является следствием требований стандарта /usr/group на блокировку сегментов. Если системный вызов fork(2) используется в программе наряду с блокировкой сегментов, то порожденный процесс при использовании любого метода блокировки должен закрыть и вновь открыть файл. В результате будет создан новый указатель текущей позиции в файле, которым можно будет манипулировать, не сталкиваясь с отмеченной проблемой. Другое решение состоит в том, чтобы использовать системный вызов fcntl(2) со значением поля l_whence 0 или 2, что делает блокировку независимой от указателя текущей позиции.




Содержание  Назад  Вперед