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




Получение информации о блокировке


Имеется возможность выявить процесс, мешающий установить блокировку. С помощью полученной информации можно узнать, какие бликоровки действуют для файла. Пусть блокировка устанавливается как в предыдущем примере, но при обращении к fcntl(2) используется операция F_GETLK. Если запрашиваемую блокировку установить нельзя, информация о первой мешающей этому блокировке будет возвращена процессу через структуру, адрес которой был передан системному вызову fcntl(2). В результате данные, переданные fcntl(2), будут заменены информацией о противодействующей блокировке. Эта информация включает два ранее не упоминавшихся элемента данных: l_pid и l_sysid. Они используются только операцией F_GETLK. (Для систем, не поддерживающих распределенную архитектуру, значение l_sysid игнорируется.) Два упомянутых поля полностью идентифицируют процесс, установивший блокировку.

Если блокировка, запрашиваемая системным вызовом fcntl(2) с использованием операции F_GETLK, может быть установлена, значением поля l_type становится F_UNLCK, а остальные поля в структуре не изменяются. Используем описанную возможность для вывода информации о всех сегментах файла, заблокированных другими процессами. Заметим, что если на один сегмент файла установлено несколько блокировок, то только первая из них будет найдена.

struct flock lck;

/* Получение и вывод информации о сегментах файла, блокированных на запись */ (void) printf ("ид-р сис. ид-р проц. тип начало длина\n"); lck.l_whence = 0; lck.l_start = 0L; lck.l_len = 0L;

do { lck.l_type = F_WRLCK; (void) fcntl (fd, F_GETLK, &lck); if (lck.l_type != F_UNLCK) { (void) printf("%9d %9d %c %6d %5d\n", lck.l_sysid, lck.l_pid, (lck.l_type == F_WRLCK) ? 'W' : 'R', lck.l_start, lck.l_len); /* Если эта блокировка заведомо покрывает остаток файла, нет нужды выявлять другие блокировки */ if (lck.l_len == 0) break; /* Иначе поищем новую блокировку после найденной */ lck.l_start += lck.l_len; } } while (lck.l_type != F_UNLCK);

Системный вызов fcntl(2) с операцией F_GETLK всегда завершается успешно (то есть процесс не будет приостановлен и вызов не завершится аварийно), если, конечно, значения переданных параметров корректны.




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