F_SETLKW
Команда F_GETLK
struct flock блокировка. Если она доступна, блокировка l_type на F_UNLCK. Другие поля остаются без изменений.Если блокировка недоступна, операционная система заполняет различные поля сведениями, описывающими уже установленные блокировки, которые препятствуют установке новой. В этом случае l_pid
Команда F_SETLK
fcntl() возвращает 0, блокировка была успешно установлена. Если она возвращает -1, блокировку установил другой процесс. В этом случае в errno устанавливается либо EAGAIN (попытайтесь снова позже) или EACCESS (нет доступа). Возможны два значения, чтобы удовлетворить старым системам.Команда F_SETLKW
F_SETLK тем, что будет ждать, пока установка блокировки не окажется возможной.Выбрав соответствующее значение для аргумента cmd
fcntl() вместе с указателем на заполненную структуру struct flock в качестве третьего аргумента:struct flock lock;
int fd;
/* ...открыть файл, заполнить struct flock... */
if (fcntl(fd, F_SETLK, &lock) < 0) {
/* Установить не удалось, попытаться восстановиться */
}
Функция lockf()
#include
int lockf(int fd, int cmd, off_t len);
Дескриптор файла fd
len указывает число блокируемых байтов: от текущего положения (назовем его pos) до pos + len байтов, если len положительно, или от pos - len до pos - 1, если len отрицательно. Команды следующие:F_LOCK
F_TLOCK
F_LOCK, но если блокировка недоступна, F_TLOCK возвращает ошибку.F_ULOCK
F_TEST
errno EACCESS.Возвращаемое значение равно 0 в случае успеха и -1 при ошибке, с соответствующим значением в errno
EAGAIN
F_TLOCK или F_TEST.EDEADLK
F_TLOCK эта операция создала бы тупик.[154]ENOLCK
Полезна комбинация F_TLOCK
EDEADLK: если вы знаете, что тупик не может возникнуть никогда, используйте F_LOCK. В противном случае, стоит обезопасить себя и использовать F_TLOCK. Если блокировка доступна, она осуществляется, но если нет, у вас появляется возможность восстановления вместо блокирования в ожидании, возможно, навечно.Завершив работу с заблокированным участком, его следует освободить. Для fcntl()
struct lock, использованную для блокирования, и измените поле l_type на F_UNLCK. Затем используйте F_SETLK в качестве аргумента cmd:lock.l_whence = ... ; /* Как раньше */
lock.l_start = ... ; /* Как раньше */
lock.l_len = ... ; /* Как раньше */
lock.l_type = F_UNLCK; /* Разблокировать */
if (fcntl(fd, F_SETLK, &lock) < 0) {
/* обработать ошибку */
}
/* Блокировка была снята */
Код, использующий lockf()
off_t curpos, len;
curpos = lseek(fd, (off_t)0, SEEK_CUR); /* Получить текущее положение */
len = ... ; / * Установить соответствующее число блокируемых байтов */
lockf(fd, F_LOCK, len); / * Осуществить блокировку */