Марк Митчелл - Программирование для Linux. Профессиональный подход
- Название:Программирование для Linux. Профессиональный подход
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2002
- Город:Москва
- ISBN:5-8459-0243-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Марк Митчелл - Программирование для Linux. Профессиональный подход краткое содержание
Данная книга в основном посвящена программированию в среде GNU/Linux. Авторы применяют обучающий подход, последовательно излагая самые важные концепции и методики использования расширенных возможностей системы GNU/Linux в прикладных программах. Читатели научатся писать программы, к интерфейсу которых привыкли пользователи Linux; освоят такие технологии, как многозадачность, многопотоковое программирование, межзадачное взаимодействие и взаимодействие с аппаратными устройствами; смогут улучшить свои программы, сделав их быстрее, надежнее и безопаснее; поймут особенности системы GNU/Linux, ее ограничения, дополнительные возможности и специфические соглашения.
Книга предназначена для программистов, уже знакомых с языком С и имеющих базовый опыт работы в GNU/Linux.
Программирование для Linux. Профессиональный подход - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
■ ru_stime. Здесь находится структура типа timeval, в которой указано, сколько системного времени (в секундах) ушло на выполнение процесса. Это время, затраченное центральным процессором на выполнение системных вызовов от имени данного процесса.
■ ru_maxrss. Это максимальный объем физической памяти, которую процесс занимал в какой-то момент своего выполнения.
В листинге 8.5 приведена функция, которая показывает, сколько пользовательского и системного времени потребил текущий процесс.
#include
#include
#include
#include
void print_cpu_time() {
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
printf("CPU time: %ld.%061d sec user, %ld.%061d sec system\n",
usage.ru_utime.tv_sec, usage.ru_utime.tv_usec,
usage.ru_stime.tv_sec, usage.ru_stime.tv_usec);
}
8.7, Функция gettimeofday(): системные часы
Функция gettimeofday()определяет текущее системное время. В качестве аргумента она принимает структуру типа timeval, в которую записывается значение времени (в секундах), прошедшее с начала эпохи UNIX (1-е января 1970 г., полночь по Гринвичу). Это значение разделяется на два поля. В поле tv_secхранится целое число секунд, а в поле tv_usec— дополнительное число микросекунд. У функции есть также второй аргумент, который должен быть равен NULL. Функция объявлена в файле .
Результат, возвращаемый функцией gettimeofday(), мало подходит для отображения на экране, поэтому существуют библиотечные функции localtime()и strftime(), преобразующие это значение в нужный формат. Функция localtime()принимает указатель на число секунд (поле tv_secструктуры timeval) и возвращает указатель на структуру типа tm. Эта структура содержит поля, заполняемые параметрами времени в соответствии с локальным часовым поясом:
■ tm_hour, tm_min, tm_sec— текущее время (часы, минуты, секунды);
■ tm_year, tm_mon, tm_day— год, месяц, день;
■ tm_wday— день недели (значение 0 соответствует воскресенью);
■ tm_yday— день года;
■ tm_isdst— флаг, указывающий, учтено ли летнее время.
Функция strftime()на основании структуры tmсоздает строку, отформатированную по заданному правилу. Формат напоминает тот, что используется в функции printf(): указывается строка с кодами, определяющими включаемые поля структуры. Например, форматная строка вида
"%Y-%m-%d %Н:%М:%S"
соответствует такому результату:
2001-01-14 13:09:42
Функции strftime()необходимо задать указатель на текстовый буфер, куда будет помещена полученная строка, длину буфера, строку формата и указатель на структуру типа tm. Следует учесть, что ни функция localtime(), ни функция strftime()не учитывают дробную часть текущего времени (поле tv_usecструктуры timeval). Об этом должен позаботиться программист.
Объявления функций localtime()и strftime()находятся в файле .
Программа, показанная в листинге 8.6, отображает текущие дату и время с точностью до миллисекунды.
#include
#include
#include
#include
void print_time() {
struct timeval tv;
struct tm* ptm;
char time_string[40];
long milliseconds;
/* Определение текущего времени и преобразование полученного
значения в структуру типа tm. */
gettimeofday(&tv, NULL);
ptm = localtime(&tv.tv_sec);
/* Форматирование значения даты и времени с точностью
до секунды. */
strftime(time_string, sizeof(time_string),
"%Y-%m-%d %H:%M:%S", ptm);
/* Вычисление количества миллисекунд. */
milliseconds = tv.tv_usec / 1000;
/* Отображение даты и времени с указанием
числа миллисекунд. */
printf("%s.%03ld\n", time_string, milliseconds);
}
8.8. Семейство функций mlock(): блокирование физической памяти
Функции семейства mlock()позволяют программе блокировать часть своего адресного пространства в физической памяти. Заблокированные страницы не будут выгружены операционной системой в раздел подкачки, даже если программа долго к ним не обращалась.
Блокирование физической памяти важно в программах реального времени, поскольку задержки, связанные с выгрузкой и подкачкой страниц, могут оказаться слишком длинными или возникать в самый неподходящий момент. Приложения, заботящиеся о безопасности своих данных, могут устанавливать запрет на выгрузку важных данных в файл подкачки, в котором они станут доступны злоумышленнику после завершения программы.
Чтобы заблокировать область памяти, достаточно вызвать функцию mlock(), передав ей указатель на начало области и значение длины области. ОС Linux разбивает память на страницы и соответственно блокирует ее постранично: любая страница, которую захватывает (хотя бы частично) заданная в функции mlock()область памяти, окажется заблокированной. Определить размер системной страницы позволяет функция getpagesize(). В Linux-системах, работающих на платформе x86, эта величина составляет 4 Кбайт.
Вот как можно выделить и заблокировать 32 Мбайт оперативной памяти:
const int alloc_size = 32 * 1024 * 1024;
char* memory = malloc(alloc_size);
mlock(memory, alloc_size);
Выделение страницы и блокирование ее с помощью функции mlock()еще не означает, что эта страница будет предоставлена данному процессу, поскольку выделение памяти может происходить в режиме копирования при записи. [29] Режим копирования при записи означает, что Linux создает для процесса частную копию страницы только тогда, когда процесс записывает в нее какие-то данные.
Следовательно, каждую страницу необходимо проинициализировать:
size_t i;
size_t page_size = getpagesize();
for (i = 0; i < alloc_size; i += page_size)
memory[i] = 0;
Процессу, осуществляющему запись на страницу, операционная система предоставит в монопольное использование ее уникальную копию.
Для разблокирования области памяти следует вызвать функцию munlock(), передав ей те же аргументы, что и функции mlock().
Функция mlockall()блокирует все адресное пространство программы и принимает единственный флаговый аргумент. Флаг MCL_CURRENTозначает блокирование всей выделенной на данный момент памяти, но не той, что будет выделяться позднее. Флаг MCL_FUTUREзадает блокирование всех страниц, выделенных после вызова функции mlockall(). Сочетание флагов MCL_CURRENT | MCL_FUTUREпозволяет блокировать всю память программы, как текущую, так и будущую.
Блокирование больших объемов памяти, особенно с помощью функции mlockall(), несет потенциальную угрозу всей системе. Несправедливое распределение оперативной памяти приведет к катастрофическому снижению производительности системы, так как остальным процессам придется сражаться друг с другом за небольшой "клочок" памяти, вследствие чего они будут постоянно выгружаться на диск и загружаться обратно. Может даже возникнуть ситуация, когда оперативная память закончится и система начнет уничтожать процессы. По этой причине функции mlock()и mlockall()доступны лишь суперпользователю. Если какой-нибудь другой пользователь попытается вызвать одну из этих функций, она вернёт значение -1, а в переменную errno будет записан код EPERM.
Интервал:
Закладка: