Основы программирования в Linux
Основы программирования в Linux читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
l_type 0, l_whence 0, l_start 10, l_len 20, l_pid 1534Testing F_RDLCK on region from 15 to 20F_RDLCK — Lock would succeed...Testing F_WRLCK on region from 25 to 30Lock would fail. F_GETLK returned:l_type 0, l_whence 0, l_start 10, l_len 20, l_pid 1534Testing F_RDLCK on region from 25 to 30F_RDLCK — Lock would succeed...Testing F_WRLCK on region from 40 to 45Lock would fail. F_GETLK returned:l_type 1, l_whence 0, l_start 40, l_len 10, l_pid 1534Testing F_RDLCK on region from 40 to 45Lock would fail. F_GETLK returned:l_type 1, l_whence 0, l_start 40, l_len 10, l_pid 1534...Testing F_RDLCK on region from 95 to 100F_RDLCK - Lock would succeedКак это работает
Для каждой группы из пяти байтов в файле программа lock4 задает структуру участка файла для тестирования блокировок, которую она потом применяет для определения того, может ли этот участок быть заблокирован для чтения или записи. Возвращаемая информация показывает байты, относящиеся к участку файла, смещение от нулевого байта, которое могло бы вызвать аварийное завершение запроса на блокировку. Поскольку поле
l_pidfcntll_pidДля того чтобы понять вывод, следует заглянуть в заголовочный файл fcntl.h (обычно /usr/include/fcntl.h) и увидеть, что поле
l_typeF_WRLCKF_RDLCKl_typel_typeДля байтов с 10-го по 30-й возможна установка разделяемой блокировки, поскольку блокировка, установленная программой lock3, не исключительная, а разделяемая. Для участка с 40-го по 50-й байт нельзя установить оба типа блокировки, поскольку lock3 задала исключительную (
F_WRLCKПосле завершения программы lock4 необходимо немного подождать, чтобы программа lock3 завершила вызов
sleepКонкурирующие блокировки
Теперь, когда вы увидели, как проверять существующие блокировки файла, давайте посмотрим, что произойдет, когда две программы состязаются за получение блокировки для одного и того же участка файла. Вы воспользуетесь снова программой lock3 для блокировки файла и новой программой lock5 для попытки установить новую блокировку файла. В завершение вы добавите в программу lock5 несколько вызовов для снятия блокировки (упражнение 7.11).
Далее приведена программа lock5.с, которая пытается заблокировать уже заблокированные участки файла вместо того, чтобы проверить состояние блокировки других частей файла.
После директив #include и объявлений откройте дескриптор файла.
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>const char *test_file = "/tmp/test_lock";int main() { int file_desc; struct flock region_to_lock; int res; file_desc = open(test_file, O_RDWR | O_CREAT, 0666); if (!file_desc) { fprintf(stderr, "Unable to open %s for read/writen", test_file); exit(EXIT_FAILURE); }В оставшейся части программы задаются разные участки файла, и делается попытка установить для них блокировки разных типов:
region_to_lock.l_type = F_RDLCK; region_to_lock.l_whence = SEEK_SET; region_to_lock.l_start = 10; region_to_lock.l_len = 5; printf("Process %d, trying F_RDLCK, region %d to %dn", getpid(), (int)region_to_lock.l_start, (int)(region_to_lock.l_start + region_to_lock.l_len)); res = fcntl(file_desc, F_SETLK, &region_to_lock); if (res == -1) { printf("Process %d - failed to lock regionn", getpid()); } else { printf("Process %d — obtained lock regionn", getpid()); } region_to_lock.l_type = F_UNLCK; region_to_lock.l_whence = SEEK_SET; region_to_lock.l_start = 10; region_to_lock.l_len = 5; printf("Process %d, trying F_UNLCK, region %d to %dn", getpid(), (int)region_to_lock.l_start, (int)(region_to_lock.l_start + region_to_lock.l_len)); res = fcntl(file_desc, F_SETLK, &region_to_lock); if (res == -1) { printf("Process %d — failed to unlock regionn", getpid()); } else { printf("Process %d — unlocked regionn", getpid());
