Следующие два элемента, l_whence
l_start
, определяют начало области тем же способом, что и файловые смещения, передаваемые в lseek()
. l_whence
сообщает о способе интерпретации l_start
и принимает одно из значений SEEK_SET
, SEEK_CUR
или SEEK_END
; более подробно эти значения рассматривались в главе 11. Следующий элемент, l_len
, сообщает размер блокировки в байтах. Если l_len
равно 0, считается, что блокировка распространяется до конца файла. Последний элемент, l_pid
, используется только тогда, когда запрашиваются блокировки. Он устанавливается в идентификатор процесса, владеющего запрашиваемой блокировкой.Существуют три команды fcntl()
fcntl()
во втором аргументе, fcntl()
возвращает -1
в случае ошибки и 0
— в противном случае. Ниже перечислены допустимые значения параметра command
.F_SETLK | Устанавливает блокировку, описанную в arg . Если блокировку невозможно выдать из-за конфликта с блокировками других процессов, возвращается EAGAIN . Если l_type устанавливается в F_UNLCK , существующая блокировка снимается. |
F_SETLKW | Подобно F_SETLK , но блокирует только при условии предоставления блокировки. Если сигнал поступает во время блокирования процесса, вызов fcntl() возвращает EAGAIN . |
F_GETLK | Проверяет возможность выдачи описанной в arg блокировки. Если блокировка предоставляется, содержимое struct flock не меняется, кроме l_type , который устанавливается в F_UNLCK . Если блокировка не выдается, l_pid устанавливается в идентификатор процесса, содержащего конфликтующую блокировку. Значение 0 возвращается независимо от того, будет ли предоставлена блокировка. |
Хотя F_GETLK
fcntl(fd, F_GETLK, &lockinfo);
if (lockinfо.l_type != F_UNLCK) {
fprintf(stderr, "конфликт блокировок\n");
return 1;
}
lockinfо.l_type = F_RDLCK;
fcntl(fd, F_SETLK, &lockinfo);
Другой процесс мог заблокировать область между двумя вызовами fcntl()
fcntl()
не удается установить блокировку.В качестве простого примера блокировки записей ниже приведена программа, которая открывает файл, устанавливает на нем блокировку чтения, освобождает блокировку чтения, устанавливает блокировку записи и закрывается. В промежутках между каждым из этих шагов программа ожидает, пока пользователь нажмет клавишу
1: /* lock.с */
2:
3: #include
4: #include
5: #include
6: #include
7:
8: /* выводит сообщение и ожидает нажатия
9: пользователем клавиши
10: void waitforuser(char * message) {
11: char buf[10];
12:
13: printf("%s", message);
14: fflush(stdout);
15:
16: fgets(buf, 9, stdin);
17: }
18:
19: /* Получает блокировку заданного типа на файловом дескрипторе fd.
20: Типом блокировки может быть F_UNLCK, F_RDLCK или F_WRLCK */
21: void getlock(int fd, int type) {
22: struct flock lockinfo;
23: char message[80];
24: