- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Linux программирование в примерах - Арнольд Роббинс
Шрифт:
Интервал:
Закладка:
Многие системы GNU/Linux предоставляют каталог /dev/shm, использующий файловую систему типа tmpfs:
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hda2 6198436 5136020 747544 88% /
/dev/hda5 61431520 27720248 30590648 48% /d
none 256616 0 256616 0% /dev/shm
Тип файловой системы tmpfs предоставляет электронный (RAM) диск: часть памяти, которая используется, как если бы она была диском. Более того, файловая система tmpfs использует механизмы виртуальной памяти ядра Linux для его увеличения сверх фиксированного размера. Если на вашей системе уйма оперативной памяти, этот подход может обеспечить заметное ускорение. Чтобы протестировать производительность, мы начали с файла /usr/share/dict/linux.words, который является отсортированным списком правильно написанных слов, по одному в строке. Затем мы перемешали этот файл, так что он больше не был сортированным, и создали больший файл, содержащий 500 копий спутанной версии файла:
$ ls -l /tmp/randwords.big /* Показать размер */
-rw-r--r-- 1 arnold devel 204652500 Sep 18 16:02 /tmp/randwords.big
$ wc -l /tmp/randwords.big /* Сколько слов? */
22713500 /tmp/randwords.big /* Свыше 22 миллионов! */
Затем мы отсортировали файл, используя сначала каталог /tmp, а затем с TMPDIR, установленным в /dev/shm[125]:
$ time sort /tmp/randwords.big > /dev/null
/* Использование реальных файлов */
real 1m32.566s
user 1m23.137s
sys 0m1.740s
$ time TMPDIR=/dev/shm sort /tmp/randwords.big > /dev/null
/* Использование электронного диска */
real 1m28.257s
user 1m18.469s
sys 0m1.602s
Интересно, использование электронного диска было лишь незначительно быстрее, чем использование обычных файлов. (В некоторых дальнейших тестах оно было даже в действительности медленнее!) Мы предполагаем, что в игру вступил буферный кэш ядра (см. раздел 4.6.2 «Создание файлов с помощью creat()»), весьма эффективно ускоряя файловый ввод/вывод[126].
У электронного диска есть важный недостаток: он ограничен сконфигурированным для вашей системы размером пространства для подкачки.[127] Когда мы попытались отсортировать файл, содержащий 1000 копий файла с перемешанными словами, место на электронном диске закончилось, тогда как обычный sort завершился благополучно.
Использовать TMPDIR для своих программ просто. Мы предлагаем следующую схему.
const char template[] = "myprog.XXXXXX";
char *tmpdir, *tfile;
size_t count;
int fd;
if ((tmpdir = getenv("TMPDIR")) == NULL)
/* Использовать значение TMPDIR, если имеется */
tmpdir = "/tmp"; /* В противном случае, /tmp по умолчанию */
count = strlen(tmpdir) + strlen(template) + 2;
/* Вычислить размер имени файла */
tfile = (char *)malloc(count); /* Выделить для него память */
if (tfile == NULL) /* Проверка ошибок */
/* восстановить */
sprintf(tfile, "%s/%s", tmpdir, template);
/* Создать завершающий шаблон */
fd = mkstemp(tfile); /* Создать и открыть файл */
/* ...использование tempfile через fd... */
close(fd); /* Очистка */
unlink(tfile);
free(tfile);
В зависимости от потребностей вашего приложения, вы можете захотеть немедленно удалить файл после его открытия, вместо его удаления как части завершающей очистки.
12.4. Совершение самоубийства: abort()
Бывают моменты, когда программа просто не может продолжаться. Обычно лучше всего при этом выдать сообщение об ошибке и вызвать exit(). Однако, особенно для ошибок, являющихся проблемами программирования, полезно не только завершиться, но и создать дамп ядра, который сохраняет в файле состояние работающей программы для последующего исследования в отладчике. В этом заключается работа функции abort():
#include <stdlib.h> /* ISO С */
void abort(void);
Функция abort() посылает сигнал SIGABRT самому процессу. Это случится, даже если SIGABRT заблокирован или игнорируется. После этого осуществляется обычное для SIGABRT действие, которое заключается в создании дампа ядра.
Примером abort() в действии является макрос assert(), описанный в начале данной главы. Когда assert() обнаруживает, что его выражение ложно, он выводит сообщение об ошибке, а затем вызывает abort() для создания дампа ядра.
В соответствии со стандартом С, осуществляет abort() очистку или нет, зависит от реализации. Под GNU/Linux она выполняет очистку: все потоки <stdio.h> FILE* перед завершением программы закрываются. Обратите, однако, внимание, что для открытых файлов, использующих системные вызовы на основе дескрипторов файлов, ничего не делается. (Если открыты лишь файлы или каналы, ничего не нужно делать. Хотя мы не обсуждали это, дескрипторы файлов используются также для сетевых соединений, и оставление их открытыми является плохой практикой.)
12.5. Нелокальные переходы
«Идите прямо в тюрьму. Не проходите GO. Не забирайте 200$».
- Монополия -Вы, без сомнения, знаете, чем является goto: передачей потока управления на метку где-то в текущей функции. Операторы goto при скупом употреблении могут послужить удобочитаемости и правильности функции (Например, когда все проверки ошибок используют goto для перехода на метку в конце функции, такую, как clean_up, код с этой меткой проводит очистку [закрывая файлы и т.п.] и возвращается.) При плохом использовании операторы goto могут привести к так называемой «лапше» в коде, логику которого становится невозможно отследить.
Оператор goto в языке С ограничен переходом на метку в текущей функции. Многие языки в семействе Алгола, такие, как Паскаль, допускают использование goto для выхода из вложенной функции в предшествующую вызывающую функцию. Однако в С нет способа, в пределах синтаксиса самого языка, перейти в определенную точку другой функции, пусть даже и вызывающей. Такой переход называется нелокальным переходом.
Почему полезен нелокальный переход? Рассмотрите интерактивную программу, которая считывает и выполняет программы. Предположим, пользователь запускает длительное задание, разочаровывается или меняет мнение о данном задании и нажимает CTRL-С для генерирования сигнала SIGINT. Когда запускается обработчик сигнала, он может перейти обратно в начало главного цикла чтения и обработки команд. Строковый редактор ed представляет простой пример этого:
$ ed -p '> ' sayings /* Запуск ed, '> ' используется как приглашение */
sayings: No such file or directory
> a /* Добавить текст */
Hello, world
Don't panic
^C /* Сгенерировать SIGINT */
? /* Сообщение об ошибке ''один размер подходит всем'' */
> 1,$p /* ed возвращается в командную строку */
Hello, world /* '1,$p' prints all the lines */
Don't panic
> w /* Сохранить файл */
25
> q /* Все сделано */
Внутри себя ed устанавливает перед циклом команд точку возврата, и обработчик сигнала осуществляет нелокальный переход на эту точку возврата.
12.5.1. Использование стандартных функций: setjmp() и longjmp()
Нелокальные переходы осуществляются с помощью функций setjmp() и longjmp(). Эти функции используются в двух разновидностях. Традиционные процедуры определены стандартом ISO С:
#include <setjmp.h> /* ISO С */
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);
Тип jmp_buf определен через typedef в <setjmp.h>. setjmp() сохраняет текущее «окружение» в env. env обычно является глобальной или статической на уровне файла переменной, так что она может использоваться из вызванной функции. Это окружение включает любую информацию, необходимую для перехода на местоположение, из которого была вызвана setjmp(). Содержание jmp_buf по своей природе машинно-зависимо; таким образом, jmp_buf является непрозрачным типом: тем, что вы используете, не зная, что находится внутри него.
setjmp() возвращает 0, когда она вызывается для сохранения в jmp_buf текущего окружения. Ненулевое значение возвращается, когда с использованием окружения осуществляется нелокальный переход:
jmp_buf command_loop; /* На глобальном уровне */
/* ... затем в main() ... */
if (setjmp(command_loop) == 0) /* Состояние сохранено, продолжить */
;
else /* Мы попадаем сюда через нелокальный переход */
printf("?n"); /* ed's famous message */

