- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Основы программирования в Linux - Нейл Мэтью
Шрифт:
Интервал:
Закладка:
Простое выделение памяти
Вы можете выделить память с помощью вызова malloc из стандартной библиотеки С:
#include <stdlib.h>
void *malloc(size_t size);
ПримечаниеИмейте в виду, что ОС Linux (следующая требованиям стандарта X/Open) отличается от некоторых реализаций UNIX тем, что не требует включения специального заголовочного файла malloc.h. Кроме того, параметр size, задающий количество выделяемых байтов, — это не простой тип int, хотя обычно он задается типом беззнаковое целое (unsigned integer).
В большинстве систем Linux вы можете выделять большой объем памяти. Давайте начнем с очень простой программы из упражнения 7.1, которая, тем не менее, выигрывает соревнование со старыми программами ОС MS-DOS, поскольку они не могут обращаться к памяти за пределами базовой карты памяти ПК объемом 640 Кбайт.
Упражнение 7.1. Простое распределение памятиНаберите следующую программу memory1.с:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define A_MEGABYTE (1024 * 1024)
int main() {
char *some_memory;
int megabyte = A_MEGABYTE;
int exit_code = EXIT_FAILURE;
some_memory = (char*)malloc(megabyte);
if (some_memory ! = NULL) {
sprintf(some_memory, "Hello Worldn");
printf("%s", some_memory);
exit_code = EXIT_SUCCESS;
}
exit(exit_code);
}
Когда вы выполните эту программу, то получите следующий вывод:
$ ./memory1
Hello World
Как это работает
Данная программа запрашивает с помощью библиотечного вызова malloc указатель на один мегабайт памяти. Вы проверяете, успешно ли завершился вызов malloc, и используете часть памяти, чтобы продемонстрировать ее наличие. Когда вы выполните программу, то увидите вывод фразы "Hello World", показывающий, что malloc действительно вернул мегабайт используемой памяти. Мы не проверяем наличие мегабайта целиком; мы приняли на веру программный код malloc!
Поскольку функция malloc возвращает указатель типа void*, вы преобразуете результат в нужный вам указатель типа char*. Эта функция возвращает память, выровненную так, что она может быть преобразована в указатель любого типа.
Простое основание — современные системы Linux применяют 32-разрядные целые и 32-разрядные указатели, что позволяет задавать до 4 Гбайт. Эта способность задавать адреса с помощью 32-разрядного указателя без необходимости применения регистров сегментов или других приемов, называется простой 32-разрядной моделью памяти. Эта модель также используется и в 32-разрядных версиях ОС Windows ХР и Vista. Тем не менее, никогда не следует рассчитывать на 32-разрядные целые, поскольку все возрастающее количество 64-разрядных версий Linux находится в употреблении.
Выделение огромных объемов памяти
Теперь, когда вы увидели, что ОС Linux преодолевает ограничения модели памяти ОС MS-DOS, давайте усложним ей задачу. Приведенная в упражнении 7.2 программа запрашивает выделение объема памяти, большего, чем физически есть в машине, поэтому можно предположить, что функция malloc начнет давать сбои при приближении к максимальному объему физической памяти, поскольку ядру и всем остальным выполняющимся процессам также нужна память.
Упражнение 7.2. Запрос на всю физическую памятьС помощью программы memory2.с мы собираемся запросить больше памяти, чем физически есть в машине. Вам нужно откорректировать определение PHY_MEM_MEGS в соответствии с физическими ресурсами вашего компьютера.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define A_MEGABYTE (1024 * 1024)
#define PHY_MEM_MEGS 1024 /* Откорректируйте это число
должным образом */
int main() {
char *some_memory;
size_t size_to_allocate = A_MEGABYTE;
int megs_obtained = 0;
while (megs_obtained < (PHY_MEM_MEGS * 2)) {
some_memory = (char *)malloc(size_to_allocate);
if (some_memory != NULL) {
megs_obtained++;
sprintf(somememory, "Hello World");
printf("%s — now allocated %d Megabytesn", some_memory, megs_obtained);
} else {
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
Далее приведен немного сокращенный вывод:
$ ./memory3
Hello World — now allocated 1 Megabytes
Hello World — now allocated 2 Megabytes
...
Hello World — now allocated 2047 Megabytes
Hello World — now allocated 2048 Megabytes
Как это работает
Программа очень похожа на предыдущий пример. Это просто циклы, запрашивающие все больше и больше памяти до тех пор, пока не будет выделено памяти вдвое больше, чем заданный вами с помощью корректировки определения PHY_MEM_MEGS объем памяти, имеющейся у вашего компьютера. Удивительно, что эта программа вообще работает, потому что мы, как оказалось, создали программу, которая использует каждый байт физической памяти на машине одного из авторов. Обратите внимание на то, что в нашем вызове malloc применяется тип size_t.
Другая интересная особенность заключается в том, что, по крайней мере, на данной машине программа выполняется в мгновение ока. Таким образом, мы не только вне сомнения использовали всю память, но и сделали это на самом деле очень быстро.
Продолжим исследование и посмотрим, сколько памяти мы сможем выделить на этой машине с помощью программы memory3.c (упражнение 7.3). Поскольку уже понятно, что система Linux способна очень умно обходиться с запросами памяти, мы каждый раз будем выделять память по 1 Кбайт и записывать данные в каждый полученный нами блок.
Упражнение 7.3. Доступная памятьДалее приведена программа memory3.c. По своей истинной природе она крайне недружественная по отношению к пользователю и может очень серьезно повлиять на многопользовательскую машину. Если вас беспокоит подобный риск, лучше совсем не запускать ее; если вы окажитесь от выполнения этой программы, усвоению материала это не повредит.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define ONE_K (1024)
int main() {
char *some_memory;
int size_to_allocate = ONE_K;
int megs_obtained = 0;
int ks_obtained = 0;
while (1) {
for (ks_obtained = 0; ks_obtained < 1024; ks_obtained++) {
some_memory = (char *)malloc(size_to_allocate);
if (some_memory == NULL) exit(EXIT_FAILURE);
sprintf(some_memory, "Hello World");
}
megs_obtained++;
printf("Now allocated %d Megabytesn", megs_obtained);
}
exit(EXIT_SUCCESS);
}
На этот раз вывод, также сокращенный, выглядит следующим образом:
$ ./memory3
Now allocated 1 Megabytes
...
Now allocated 1535 Megabytes
Now allocated 1536 Megabytes
Out of Memory: Killed process 2365
Killed
После этого программа завершается. Она выполняется несколько секунд и существенно замедляется при приближении к размеру, равному объему физической памяти на компьютере, а также активно использует жесткий диск. Тем не менее программа выделяла и получала доступ к области памяти, большей по размеру объема физической памяти, которая была установлена на машине одного из авторов во время написания этой главы. В конце концов, система защищает себя от этой довольно агрессивной программы и уничтожает ее. В некоторых системах она может тихо закончить выполнение, когда функция malloc завершается аварийно.
Как это работает
Память, выделяемая приложению, управляется ядром системы Linux. Каждый раз, когда программа запрашивает память, пытается записывать в память или считывать из памяти, которая была выделена, ядро Linux решает, как обрабатывать этот запрос.
Сначала ядро может использовать свободную физическую память для удовлетворения запроса приложения на выделение памяти, но когда физическая память исчерпана, ядро начинает использовать так называемую область свопинга или подкачки. В ОС Linux это отдельная область диска, выделяемая во время инсталляции системы. Если вы знакомы с ОС Windows, функционирование области свопинга в Linux немного напоминает файл подкачки в Windows. Но в отличие от ОС Windows при написании программного кода не нужно беспокоиться ни о локальной, ни о глобальной динамической памяти (heap), ни о выгружаемых сегментах памяти — ядро Linux все организует для вас.
Ядро перемещает данные и программный код между физической памятью и областью свопинга так, что при каждом чтении из памяти или записи в нее данные кажутся находящимися в физической памяти, где бы они не находились на самом деле перед вашей попыткой обратиться к ним.

