- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Linux программирование в примерах - Арнольд Роббинс
Шрифт:
Интервал:
Закладка:
Отличительными моментами flock() являются следующие:
• Блокировка с помощью flock() является вспомогательной; программа, не использующая блокировку, может прийти и испортить без всяких сообщений об ошибках файл, заблокированный с помощью flock().
• Блокируется весь файл. Нет механизма для блокировки только части файла.
• То, как был открыт файл, не влияет на тип блокировки, который может быть использован. (Сравните это с fcntl(), при использовании которой файл должен быть открыт для чтения для получения блокировки чтения, или для записи для блокировки записи.)
• Несколько открытых для одного и того же файла дескрипторов используют совместную блокировку. Для удаления блокировки может использоваться любой из них. В отличие от fcntl(), когда нет явного разблокирования, блокировка не удаляется до тех пор, пока не будут закрыты все открытые дескрипторы файла.
• Процесс может иметь лишь одну блокировку файла с помощью flock(); последовательный вызов flock() с двумя различными типами блокировок изменяет тип блокировки на новый.
• На системах GNU/Linux блокировки flock() совершенно независимы от блокировок fcntl(). Многие коммерческие системы Unix реализуют flock() в виде «оболочки» поверх fcntl(), но их семантика различается.
Мы не рекомендуем использовать flock() в новых программах, поскольку ее семантика не такая гибкая и поскольку она не стандартизована POSIX. Поддержка ее в GNU/Linux осуществляется главным образом для обратной совместимости с программным обеспечением, написанным для старых систем BSD Unix.
ЗАМЕЧАНИЕ. Справочная страница GNU/Linux flock(2) предупреждает, что блокировки flock() не работают для смонтированных удаленных файлов. Блокировки fcntl() работают, при условии, что у вас достаточно новая версия Linux и сервер NFS поддерживает блокировки файлов
14.2.4. Обязательная блокировка
Большинство коммерческих систем Unix поддерживают в дополнение к вспомогательной обязательную блокировку файлов. Обязательная блокировка работает лишь с fcntl(). Обязательная блокировка файла контролируется установками прав доступа файла, в частности, путем добавления к файлу бита setgid с помощью команды chmod.
$ echo hello, world > myfile /* Создать файл */
$ ls -l myfile /* Отобразить права доступа */
-rw-r--r-- 1 arnold devel 13 Apr 3 17:11 myfile
$ chmod g+s myfile /* Добавить бит setgid */
$ ls -l myfile /* Показать новые права доступа */
-rw-r-Sr-- 1 arnold devel 13 Apr 3 17:11 myfile
Бит права на исполнение группой должен быть оставлен сброшенным. S показывает, что бит setgid установлен, но что бит права на исполнение — нет; если бы были установлены оба бита, была бы использована строчная буква s.
Комбинация установленного бита setgid и сброшенного бита права на исполнение группой обычно бессмысленно. По этой причине, она была выбрана разработчиками System V для обозначения «использования обязательного блокирования». И в самом деле, добавления этого бита достаточно, чтобы заставить коммерческую систему Unix, такую как Solaris, использовать блокировку файлов.
На системах GNU/Linux несколько другая история. Для обязательных блокировок файл должен иметь установленный бит setgid, но этого одного недостаточно. Файловая система, содержащая файл, также должна быть смонтирована с опцией mand в команде mount.
Мы уже рассмотрели файловые системы, разделы диска, монтирование и команду mount, главным образом, в разделе 8.1 «Монтирование и демонтирование файловых систем». Мы можем продемонстрировать обязательную блокировку с помощью небольшой программы и файловой системой для тестирования на гибком диске. Для начала, вот программа:
1 /* ch14-lockall.c --- Демонстрация обязательной блокировки. */
2
3 #include <stdio.h> /* для fprintf(), stderr, BUFSIZ */
4 #include <errno.h> /* объявление errno */
5 #include <fcntl.h> /* для флагов open() */
6 #include <string.h> /* объявление strerror() */
7 #include <unistd.h> /* для ssize_t */
8 #include <sys/types.h>
9 #include <sys/stat.h> /* для mode_t */
10
11 int
12 main(int argc, char **argv)
13 {
14 int fd;
15 int i, j;
16 mode_t rw_mode;
17 static char message[] = "hello, worldn";
18 struct flock lock;
19
20 if (argc != 2) {
21 fprintf(stderr, "usage: %s filen", argv[0]);
22 exit(1);
23 }
24
25 rw_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; / * 0644 */
26 fd = open(argv[1], O_RDWR|O_TRUNC|O_CREAT|O_EXCL, rw_mode);
27 if (fd < 0) {
28 fprintf(stderr, "%s: %s: cannot open for read/write: %sn",
29 argv[0], argv[1], strerror(errno));
30 (void)close(fd);
31 return 1;
32 }
33
34 if (write(fd, message, strlen(message)) != strlen(message)) {
35 fprintf(stderr, "%s: %s: cannot write: %sn",
36 argv[0], argv[1], strerror(errno));
37 (void)close(fd);
38 return 1;
39 }
40
41 rw_mode |= S_ISGID; /* добавить бит обязательной блокировки */
42
43 if (fchmod(fd, rw_mode) < 0) {
44 fprintf(stderr, "%s: %s: cannot change mode to %o: %sn",
45 argv[0], argv[1], rw_mode, strerror(errno));
46 (void)close(fd);
47 return 1;
48 }
49
50 /* заблокировать файл */
51 memset(&lock, ' ', sizeof(lock));
52 lock.l_whence = SEEK_SET;
53 lock.l_start = 0;
54 lock.l_len =0; /* блокировка всего файла */
55 lock.l_type = F_WRLCK; /* блокировка записи */
56
57 if (fcntl(fd, F_SETLK, &lock) < 0) {
58 fprintf(stderr, "%s: %s: cannot lock the file: %sn",
59 argv[0], argv[1], strerror(errno));
60 (void)close(fd);
61 return 1;
62 }
63
64 pause();
65
66 (void)close(fd);
67
68 return 0;
69 }
Программа устанавливает права доступа и создает файл, указанный в командной строке (строки 25 и 26). Затем она записывает в файл некоторые данные (строка 34). Строка 41 добавляет к правам доступа бит setgid, а строка 43 изменяет их. (Системный вызов fchmod() обсуждался в разделе 5.5.2 «Изменение прав доступа: chmod() и fchmod()».)
Строки 51–55 устанавливают struct flock для блокировки всего файла, а затем блокировка осуществляется реально в строке 57. Выполнив блокировку, программа засыпает, используя системный вызов pause() (см. раздел 10.7 «Сигналы для межпроцессного взаимодействия»). После этого программа закрывает дескриптор файла и завершается. Вот расшифровка с комментариями, демонстрирующая использование обязательной блокировки файлов:
$ fdformat /dev/fd0 /* Форматировать гибкий диск */
Double -sided, 80 tracks, 18 sec/track. Total capacity 1440 kB.
Formatting ... done
Verifying ... done
$ /sbin/mke2fs /dev/fd0 /* Создать файловую систему Linux */
/* ...множество вывода опущено... */
$ su /* Стать root, чтобы использовать mount */
Password: /* Пароль не отображается */
# mount -t ext2 -о mand /dev/fd0 /mnt/floppy /* Смонтировать гибкий
диск, с возможностью блокировок */
# suspend /* Приостановить оболочку root */
[1]+ Stopped su
$ ch14-lockall /mnt/floppy/x & /* Фоновая программа */
[2] 23311 /* содержит блокировку */
$ ls -l /mnt/floppy/x /* Посмотреть файл */
-rw-r-Sr-- 1 arnold devel 13 Apr 6 14:23 /mnt/floppy/x
$ echo something > /mnt/floppy/x /* Попытаться изменить файл */
bash2: /mnt/floppy/x: Resource temporarily unavailable
/* Возвращается ошибка */
$ kill %2 /* Завершить программу с блокировкой */
$ /* Нажать ENTER */
[2]- Terminated ch14-lockall /mnt/floppy/x /* Программа завершена */
$ echo something > /mnt/floppy/x /* Новая попытка изменения работает */
$ fg /* Вернуться в оболочку root */
su
# umount /mnt/floppy /* Демонтировать гибкий диск */
# exit /* Работа с оболочкой root закончена */
$
Пока выполняется ch14-lockall, она владеет блокировкой. Поскольку это обязательная блокировка, перенаправления ввода/вывода оболочки завершаются неудачей. После завершения ch14-lockall блокировки освобождаются, и перенаправление ввода/вывода достигает цели. Как упоминалось ранее, под GNU/Linux даже root не может аннулировать обязательную блокировку файла.
Немного отклоняясь в сторону, гибкие диски представляют отличный испытательный стенд для изучения того, как использовать инструменты, работающие с файловыми системами. Если вы сделаете что-то, что разрушит данные на гибком диске, это вряд ли будет катастрофическим, тогда как экспериментирование с действующими разделами на обычных жестких дисках значительно более рискованно.

