25: /* будет блокироваться весь файл */
26: lockinfo.l_whence = SEEK_SET;
27: lockinfo.l_start = 0;
28: lockinfo.l_len = 0;
29:
30: /* продолжать попытки, пока того желает пользователь */
31: while (1) {
32: lockinfo.l_type = type;
33: /* если блокировка получена, немедленно возвратиться */
34: if (!fcntl(fd, F_SETLK, &lockinfo)) return;
35:
36: /* найти, кто удерживает конфликтующую блокировку */
37: fcntl(fd, F_GETLK, &lockinfo);
38:
39: /* есть шанс, что блокировка освобождена между F_SETLK
40: и F_GETLK; проверить, существует ли еще конфликт
41: перед тем, как сообщать об этом */
42: if (lockinfo.l_type != F_UNLCK) {
43: sprintf (message, "конфликт с процессом %d... нажмите "
44: "
45: waitforuser(message);
46: }
47: }
48: }
49:
50: int main(void) {
51: int fd;
52:
53: /* подготовить файл для блокировки */
54: fd = open("testlockfile", O_RDWR | O_CREAT, 0666);
55: if (fd < 0) {
56: perror("open");
57: return 1;
58: }
59:
60: printf("получение блокировки чтения\n");
61: getlock(fd, F_RDLCK);
62: printf("блокировка чтения получена\n");
63:
64: waitforuser("\nдля продолжения нажмите
65:
66: printf("освобождение блокировки\n");
67: getlock(fd, F_UNLCK);
68:
69: printf("получение блокировки записи\n");
70: getlock(fd, F_WRLCK);
71: printf("блокировка записи получена\n");
72:
73: waitforuser("\nдля завершения нажмите
74:
75: /* при закрытии файла блокировки освобождаются */
76:
77: return 0;
78: }
С блокировками следует обращаться иначе, чем с другими файловыми атрибутами. Блокировки ассоциируются с парой
1. Открытие одного файла дважды, что дает два разных файловым дескриптора.
2. Поучение блокировки чтения на одной области в обоих файловых дескрипторах.
3. Закрытие одного из файловых дескрипторов.
Выдана лишь одна блокировка чтения, потому что была задействована только одна пара
После fork()
родительский процесс сохраняет свои файловые блокировки, но дочерний процесс — нет. Если бы дочерние процессы наследовали блокировки, два процесса пришли бы, в конечном счете, к блокировке записи на одной области файла.
Однако файловые блокировки наследуются в exec()
. Поскольку в POSIX не определено, что происходит с блокировками после exec()
, все варианты Unix сохраняют их[92].
13.3.3. Обязательные блокировки
И Linux, и System V поддерживают как обычные, так и обязательные блокировки. Обязательные блокировки устанавливаются и реализуются с помощью того же механизма fcntl()
, который используется для рекомендательной блокировки записей. Блокировки считаются обязательными, если бит setgid заблокированного файла установлен, но его бит группового выполнения — нет. В противном случае применяется рекомендательное блокирование.