- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Основы программирования в Linux - Нейл Мэтью
Шрифт:
Интервал:
Закладка:
} else {
printf("Process %d — unlocked regionn", getpid());
}
region_to_lock.l_type = F_UNLCK;
region_to_lock.l_whence = SEEK_SET;
region_to_lock.l_start = 0;
region_to_lock.l_len = 50;
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, ®ion_to_lock);
if (res == -1) {
printf("Process %d — failed to unlock regionn", getpid());
} else {
printf("Process %d — unlocked regionn", getpid());
}
region_to_lock.l_type = F_WRLCK;
region_to_lock.l_whence = SEEK_SET;
region_to_lock.lstart = 16;
region_to_lock.l_len = 5;
printf("Process %d, trying F_WRLCK, 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, ®ion_to_lock);
if (res == -1) {
printf("Process %d — failed to lock regionn", getpid());
} else {
printf("Process %d — obtained lock on regionn", getpid());
}
region_to_lock.l_type = F_RDLCK;
region_to_lock.l_whence = SEEK_SET;
region_to_lock.l_start = 40;
region_to_lock.l_len = 10;
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(filedesc, F_SETLK, ®ion_to_lock);
if (res == -1) {
printf("Process %d — failed to lock regionn", getpid());
} else {
printf("Process %d — obtained lock on regionn", getpid());
}
region_to_lock.l_type = F_WRLCK;
region_to_lock.l_whence = SEEK_SET;
region_to_lock.l_start = 16;
region_to_lock. l_len = 5;
printf("Process %d, trying F_WRLCK with wait, 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_SETLKW, ®ion_to_lock);
if (res == -1) {
printf("Process %d — failed to lock regionn", getpid());
} else {
printf("Process %d — obtained lock, on regionn", getpid());
}
printf ("Process %d endingn", getpid());
close(file_desc);
exit(EXIT_SUCCESS);
}
Если вы сначала запустите программу lock3 в фоновом режиме, далее сразу запускайте новую программу:
$ ./lock3 &
$ process 227 locking file
$ ./lock5
Вы получите следующий вывод:
Process 227 locking file
Process 228, trying F_RDLCK, region 10 to 15
Process 228 — obtained lock on region
Process 228, trying F_UNLCK, region 10 to 15
Process 228 — unlocked region
Process 228, trying F_UNLCK, region 0 to 50
Process 228 — unlocked region
Process 228, trying F_WRLCK, region 16 to 21
Process 228 — failed to lock on region
Process 228, trying F_RDLCK, region 4 0 to 50
Process 228 - failed to lock on region
Process 228, trying F_WRLCK with wait, region 16 to 21
Process 227 closing file
Process 228 — obtained lock on region
Process 228 ending
Как это работает
Сначала программа пытается заблокировать участок с 10-го по 15-й байты с помощью разделяемой блокировки. Эта область уже заблокирована блокировкой того же типа, но одновременные разделяемые блокировки допустимы, и установка блокировки завершается успешно.
Затем программа снимает свою разделяемую блокировку с участка файла, и эта операция тоже завершается успешно. Далее она пытается разблокировать первые 50 байтов файла, даже если у них нет никакой блокировки. Это действие тоже завершается успешно, потому что, несмотря на то, что программа не установила блокировок на этот участок, конечный результат запроса на снятие блокировки заключается в констатации того, что для первых 50 байтов данная программа не поддерживает никаких блокировок.
Далее программа пытается заблокировать участок с 16-то по 21-й байты исключительной блокировкой. Эта область уже заблокирована разделяемой блокировкой, поэтому новая попытка блокировки завершается аварийно, т.к. не может быть создана исключительная блокировка.
После этого программа пробует установить разделяемую блокировку на участок с 40-го по 50-й байты. Эта область уже заблокирована исключительной блокировкой, поэтому данная операция снова завершается аварийно.
В заключение программа опять пытается получить исключительную блокировку для участка с 16-го по 21-й байты, но в этот раз она применяет команду F_SETLKW, позволяющую ждать до тех пор, пока блокировка не будет установлена. В выводе наступает долгая пауза, длящаяся, пока программа lock3, заблокировавшая этот участок, завершает вызов sleep и закрывает файл, тем самым снимая все установленные блокировки. Программа lock5 возобновляет выполнение, успешно блокирует участок файла и затем тоже завершается.
Другие команды блокировок
Есть второй метод блокировки файлов — функция lockf. Она тоже действует, используя дескрипторы файлов.
У функции следующий прототип:
#include <unistd.h>
int lockf(int fildes, int function, off_t size_to_lock);
Параметр function может принимать следующие значения:
□ F_ULOCK — разблокировать;
□ F_LOCK — заблокировать монопольно;
□ F_TLOCK — проверить и заблокировать монопольно;
□ F_TEST — проверить наличие блокировок других процессов.
Параметр size_to_lock содержит количество обрабатываемых байтов, отсчитываемых в файле от текущей величины смещения. У функции lockf более простой интерфейс, чем у вызова fcntl в основном потому, что у нее меньше функциональных возможностей и гибкости. Для применения функции вы должны найти начало участка, который хотите заблокировать, затем вызвать функцию, указав количество блокируемых байтов.
Как и в случае вызова fcntl, все блокировки только рекомендательные; они на самом деле не могут помешать чтению из файла или записи в файл. За проверку имеющихся блокировок отвечают программы. Эффект от смешивания блокировок с помощью fcntl и блокировок с помощью lockf непредсказуем, поэтому вам следует решить, какой способ выбрать, и строго его придерживаться.
Взаимоблокировки
Обсуждение блокировок не было бы законченным без упоминания об опасности взаимоблокировок или тупиков. Предположим, что две программы хотят обновить один и тот же файл. Им обеим нужно обновить байт 1 и байт 2 одновременно. Программа А выбирает первым обновление байта 2, затем байта 1. Программа В пытается обновить сначала байт 1, затем байт 2.
Обе программы стартуют одновременно. Программа А блокирует байт 2, а программа В — байт 1. Программа А пытается установить блокировку для байта 1. Поскольку он уже заблокирован программой В, программа А ждет. Программа В пытается заблокировать байт 2. Поскольку он уже заблокирован программой А, программа В тоже ждет.
Ситуация, в которой ни одна программа не может выполняться, называется взаимоблокировкой или тупиковой ситуацией. Эта проблема очень распространена в работающих с базами данных приложениях, в которых многие пользователи часто пытаются получить доступ к одним и тем же данным. Многие коммерческие реляционные базы данных обнаруживают взаимоблокировки и устраняют их автоматически; ядро Linux этого не делает. Для устранения возникшего непорядка требуется внешнее вмешательство, возможно, принудительно завершающее выполнение одной из программ.
Программистам стоит опасаться подобных ситуаций. Если у вас есть несколько программ ждущих установки блокировок, нужно быть очень внимательным и рассмотреть возможность возникновения тупиковой ситуации. В данном примере этого легко избежать: обе программы просто должны блокировать нужные им байты в одном и том же порядке или использовать область большего размера для блокировки.
ПримечаниеВ этой книге из-за ограниченности объема у нас нет возможности рассматривать трудности действующих одновременно программ. Если вы хотите почитать побольше об этом, попробуйте найти книгу: Ben-Ari М. Principles of Concurrent and Distributed Programming. — Prentice Hall, 1990 (Бен-Ари M. Принципы параллельного и распределенного программирования).
Базы данных
Вы научились использованию файлов для хранения данных, зачем применять для этого базы данных? Очень просто, в некоторых обстоятельствах средства баз данных предоставляют лучший способ решения проблем. Применение базы данных лучше, чем хранение файлов, по двум причинам:
□ вы можете хранить записи данных переменного размера, что довольно трудно реализовать с помощью простых неструктурированных файлов;
□ базы данных эффективнее хранят и извлекают данные, применяя индекс. Это большое преимущество, потому что этот индекс должен быть не просто номером записи, который легко было бы реализовать в обычном файле, а произвольной строкой.
База данных dbm
Все версии Linux и большая часть вариантов систем UNIX поставляются с базовым, но очень эффективным набором подпрограмм для хранения данных, называемым базой данных dbm. База данных dbm отлично подходит для хранения индексированных данных, которые относительно статичны. Некоторые консерваторы в области баз данных могут возразить, что dbm — вовсе не база данных, а просто система хранения индексных файлов. Стандарт X/Open, тем не менее, называет dbm базой данных, поэтому в книге мы будем продолжать называть ее так же.

