Выбрать главу

8.7, Функция gettimeofday(): системные часы

Функция gettimeofday() определяет текущее системное время. В качестве аргумента она принимает структуру типа timeval, в которую записывается значение времени (в секундах), прошедшее с начала эпохи UNIX (1-е января 1970 г., полночь по Гринвичу). Это значение разделяется на два поля. В поле tv_sec хранится целое число секунд, а в поле tv_usec — дополнительное число микросекунд. У функции есть также второй аргумент, который должен быть равен NULL. Функция объявлена в файле <sys/time.h>.

Результат, возвращаемый функцией 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() находятся в файле <time.h>.

Программа, показанная в листинге 8.6, отображает текущие дату и время с точностью до миллисекунды.

Листинг 8.6. (print-time.c) Отображение даты и времени

#include <stdio.h>

#include <sys/time.h>

#include <time.h>

#include <unistd.h>

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 Мбайт оперативной памяти: