Чтение онлайн

на главную - закладки

Жанры

Основы программирования в Linux
Шрифт:

Lock would fail. F_GETLK returned:

l_type 0, l_whence 0, l_start 10, l_len 20, l_pid 1534

Testing F_RDLCK on region from 25 to 30

F_RDLCK — Lock would succeed

...

Testing F_WRLCK on region from 40 to 45

Lock 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 40 to 45

Lock 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 100

F_RDLCK - Lock would succeed

Как это работает

Для каждой группы из пяти байтов в файле программа lock4 задает структуру участка файла для тестирования блокировок, которую она потом применяет для определения того, может ли этот участок быть заблокирован для чтения или записи. Возвращаемая информация показывает байты, относящиеся к участку файла, смещение от нулевого байта, которое могло бы вызвать аварийное завершение запроса на блокировку. Поскольку поле

l_pid
возвращаемой структуры содержит идентификатор программы, владеющей в данный момент заблокированным файлом, программа задает ему значение -1 (некорректное значение) и затем проверяет, изменилось ли оно после завершения вызова
fcntl
. Если участок в данный момент не заблокирован, поле
l_pid
не изменится.

Для того чтобы понять вывод, следует заглянуть в заголовочный файл fcntl.h (обычно /usr/include/fcntl.h) и увидеть, что поле

l_type
, равное 1, вытекает из определения
F_WRLCK
как 1, а равное 0 из определения
F_RDLCK
как 0. Таким образом, поле
l_type
, равное 1, говорит о том, что блокировка не будет установлена, поскольку существует блокировка на запись, а поле
l_type
, равное 0, свидетельствует о существовании блокировки на чтение. Для тех участков файла, которые не заблокировала программа lock3, могут быть установлены и разделяемая, и исключительная блокировки.

Для байтов с 10-го по 30-й возможна установка разделяемой блокировки, поскольку блокировка, установленная программой lock3, не исключительная, а разделяемая. Для участка с 40-го по 50-й байт нельзя установить оба типа блокировки, поскольку lock3 задала исключительную (

F_WRLCK
) блокировку для этого участка.

После завершения программы lock4 необходимо немного подождать, чтобы программа lock3 завершила вызов

sleep
и закончила выполнение.

Конкурирующие блокировки

Теперь, когда вы увидели, как проверять существующие блокировки файла, давайте посмотрим, что произойдет, когда две программы состязаются за получение блокировки для одного и того же участка файла. Вы воспользуетесь снова программой lock3 для блокировки файла и новой программой lock5 для попытки установить новую блокировку файла. В завершение вы добавите в программу lock5 несколько вызовов для снятия блокировки (упражнение 7.11).

Упражнение 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/write\n", 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 %d\n", 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 region\n", getpid);

 } else {

printf("Process %d — obtained lock region\n", 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 %d\n", 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 region\n", getpid);

 } else {

printf("Process %d — unlocked region\n", getpid);

 }

 region_to_lock.l_type = F_UNLCK;

 region_to_lock.l_whence = SEEK_SET;

Поделиться:
Популярные книги

Идеальный мир для Лекаря 13

Сапфир Олег
13. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 13

Кай из рода красных драконов 4

Бэд Кристиан
4. Красная кость
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Кай из рода красных драконов 4

Эволюционер из трущоб. Том 3

Панарин Антон
3. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
6.00
рейтинг книги
Эволюционер из трущоб. Том 3

Корсар

Русич Антон
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
6.29
рейтинг книги
Корсар

Моров. Том 5

Кощеев Владимир
4. Моров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Моров. Том 5

Деревенщина в Пекине

Афанасьев Семён
1. Пекин
Фантастика:
попаданцы
дорама
фантастика: прочее
5.00
рейтинг книги
Деревенщина в Пекине

Алекс и Алекс

Афанасьев Семен
1. Алекс и Алекс
Фантастика:
боевая фантастика
6.83
рейтинг книги
Алекс и Алекс

Студиозус

Шмаков Алексей Семенович
3. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Студиозус

На границе империй. Том 2

INDIGO
2. Фортуна дама переменчивая
Фантастика:
космическая фантастика
7.35
рейтинг книги
На границе империй. Том 2

Двойник короля 11

Скабер Артемий
11. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 11

По осколкам твоего сердца

Джейн Анна
2. Хулиган и новенькая
Любовные романы:
современные любовные романы
5.56
рейтинг книги
По осколкам твоего сердца

Афганский рубеж 2

Дорин Михаил
2. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Афганский рубеж 2

Звездная Кровь. Изгой VII

Елисеев Алексей Станиславович
7. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
технофэнтези
рпг
фантастика: прочее
попаданцы
5.00
рейтинг книги
Звездная Кровь. Изгой VII

Двойник Короля 10

Скабер Артемий
10. Двойник Короля
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Двойник Короля 10