Читаем Linux API. Исчерпывающее руководство полностью

Существующую разделяемую блокировку можно преобразовать в эксклюзивную (и наоборот), выполнив еще один вызов flock() и указав соответствующее значение для аргумента operation. Эта процедура заблокируется, если другой процесс уже удерживает разделяемую блокировку для данного файла (разве что было задано значение LOCK_NB — тогда этого не произойдет).

Атомарность операции преобразования блокировки не гарантируется. В ходе ее выполнения сначала удаляется существующая блокировка, а затем устанавливается новая. Между этими двумя действиями другой процесс может успеть получить несовместимую блокировку. В данном случае преобразование будет либо заблокировано, либо, если указан режим LOCK_NB, завершено с ошибкой, а процесс потеряет исходную блокировку (такая ситуация была характерна для оригинальной версии flock() в системе BSD и до сих пор встречается в ряде других реализаций UNIX).

Вызов flock() хоть и не является частью стандарта SUSv3, но поддерживается в большинстве реализаций UNIX. Некоторые из них требуют подключения заголовочного файла или вместо . Поскольку данный вызов берет свое начало в системе BSD, блокировки, устанавливаемые им, иногда называют файловыми BSD-блокировками.

Применение вызова flock() демонстрируется в листинге 51.1. Эта программа блокирует файл и, перейдя в режим сна на заданное количество секунд, разблокирует его обратно. Она принимает три аргумента командной строки. Первый из них представляет файл, подлежащий блокировке. Второй определяет ее тип (разделяемая или эксклюзивная) и необходимость включения флага LOCK_NB (неблокирующий режим). Третий аргумент обозначает количество секунд, которое должно пройти между блокировкой и разблокировкой; он не является обязательным и по умолчанию равен 10 секундам.

Листинг 51.1. Использование вызова flock()

filelock/t_flock.c

#include

#include

#include "curr_time.h" /* Объявление currTime() */

#include "tlpi_hdr.h"

int

main(int argc, char *argv[])

{

int fd, lock;

const char *lname;

if (argc < 3 || strcmp(argv[1], "-help") == 0 ||

strchr("sx", argv[2][0]) == NULL)

usageErr("%s file lock [sleep-time]\n"

" 'lock' is 's' (shared) or 'x' (exclusive)\n"

" optionally followed by 'n' (nonblocking)\n"

" 'sleep-time' specifies time to hold lock\n", argv[0]);

lock = (argv[2][0] == 's')? LOCK_SH: LOCK_EX;

if (argv[2][1] == 'n')

lock |= LOCK_NB;

fd = open(argv[1], O_RDONLY); /* Открываем файл, который нужно заблокировать */

if (fd == -1)

errExit("open");

lname = (lock & LOCK_SH)? "LOCK_SH": "LOCK_EX";

printf("PID %ld: requesting %s at %s\n", (long) getpid(), lname, currTime("%T"));

if (flock(fd, lock) == -1) {

if (errno == EWOULDBLOCK)

fatal("PID %ld: already locked — bye!", (long) getpid());

else

errExit("flock (PID=%ld)", (long) getpid());

}

printf("PID %ld: granted %s at %s\n", (long) getpid(), lname, currTime("%T"));

sleep((argc > 3)? getInt(argv[3], GN_NONNEG, "sleep-time"): 10);

printf("PID %ld: releasing %s at %s\n", (long) getpid(),

lname, currTime("%T"));

if (flock(fd, LOCK_UN) == -1)

errExit("flock");

exit(EXIT_SUCCESS);

}

filelock/t_flock.c

С помощью программы из листинга 51.1 можно выполнить ряд экспериментов, помогающих изучить поведение вызова flock(). Отдельные примеры показаны в следующей сессии командной строки. Сначала создадим файл, после чего запустим экземпляр нашей программы, который будет находиться в фоне, удерживая блокировку на протяжении 60 секунд:

$ touch tfile

$ ./t_flock tfile s 60 &

[1] 9777

PID 9777: requesting LOCK_SH at 21:19:37

PID 9777: granted LOCK_SH at 21:19:37

Теперь запустим еще один экземпляр той же программы, который успешно запрашивает и снимает разделяемую блокировку:

$ ./t_flock tfile s 2

PID 9778: requesting LOCK_SH at 21:19:49

PID 9778: granted LOCK_SH at 21:19:49

PID 9778: releasing LOCK_SH at 21:19:51

Но если запустить еще один экземпляр данной программы, который попытается получить эксклюзивную блокировку в неблокирующем режиме, то его запрос будет немедленно отклонен:

$ ./t_flock tfile xn

PID 9779: requesting LOCK_EX at 21:20:03

PID 9779: already locked — bye!

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

$ ./t_flock tfile x

PID 9780: requesting LOCK_EX at 21:20:21

PID 9777: releasing LOCK_SH at 21:20:37

PID 9780: granted LOCK_EX at 21:20:37

PID 9780: releasing LOCK_EX at 21:20:47

51.2.1. Семантика наследования и снятия блокировок

Перейти на страницу:

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных

Все жанры