9 lock.l_len = len; /* количество байтов. 0 – до конца файла */
10 if (fcntl(fd, F_GETLK, &lock) == –1)
11 return(-1); /* непредвиденная ошибка */
12 if (lock.l_type == F_UNLCK)
13 return(0); /* false, область не заблокирована другим процессом */
14 return(lock.l_pid); /* true, возвращается положительный PID процесса. заблокировавшего ресурс */
15 }
9.4. Рекомендательная блокировка
Блокировка записей по стандарту Posix называется рекомендательной. Ядро хранит информацию обо всех заблокированных различными процессами файлах, но оно не предотвращает запись в заблокированный на чтение процесс. Ядро также не предотвращает чтение из файла, заблокированного на запись. Процесс может игнорировать рекомендательную блокировку (advisory lock) и действовать по своему усмотрению (если у него имеются соответствующие разрешения на чтение и запись).
Рекомендательные блокировки отлично подходят для сотрудничающих процессов (cooperating processes). Примером сотрудничающих процессов являются сетевые демоны: все они находятся под контролем системного администратора. Пока в файл, содержащий порядковый номер, запрещена запись, никакой процесс не сможет его изменить.
Пример: несотрудничающие процессы
Мы можем проиллюстрировать рекомендательный характер блокировок, запустив два экземпляра нашей программы, один из которых (lockfcntl) использует функции из листинга 9.3 и блокирует файл перед увеличением последовательного номера, а другой (locknone) использует функции из листинга 9.1 и не устанавливает никаких блокировок:
solaris % lockfcntl & locknone &
lockfcntl: pid = 18816, seq# = 1
lockfcntl: pid = 18816, seq# = 2
lockfcntl: pid = 18816, seq# = 3
lockfcntl: pid = 18816, seq# = 4
lockfcntl: pid = 18816, seq# = 5
lockfcntl: pid = 18816, seq# = 6
lockfcntl: pid = 18816, seq# = 7
lockfcntl: pid = 18816, seq# = 8
lockfcntl: pid = 18816, seq# = 9
lockfcntl: pid = 18816, seq# = 10
lockfcntl: pid = 18816, seq# = 11
locknone: pid = 18817, seq# = 11
locknone: pid = 18817, seq# = 12
locknone: pid = 18817, seq# = 13
locknone: pid = 18817, seq# = 14
locknone: pid = 18817, seq# = 15
locknone: pid = 18817, seq# = 16
locknone: pid = 18817, seq# = 17
locknone: pid = 18817, seq# = 18
lockfcntl: pid = 18816, seq# = 12
lockfcntl: pid = 18816, seq# = 13
lockfcntl: pid = 18816, seq# = 14
lockfcntl: pid = 18816, seq# = 15
lockfcntl: pid = 18816, seq# = 16
lockfcntl: pid = 18816, seq# = 17
lockfcntl: pid = 18816, seq# = 18
lockfcntl: pid = 18816, seq# = 19
lockfcntl: pid = 18816, seq# = 20
locknone: pid = 18817, seq# = 19
locknone: pid = 18817, seq# = 20
locknone: pid = 18817, seq# = 21
locknone: pid = 18817, seq# = 22
locknone: pid = 18817, seq# = 23
locknone: pid = 18817, seq# = 24
locknone: pid = 18817, seq# = 25
locknone: pid = 18817, seq# = 26
locknone: pid = 18817, seq# = 27
locknone: pid = 18817, seq# = 28
locknone: pid = 18817, seq# = 29
locknone: pid = 18817, seq# = 30