- •Абсолютное и относительное время
- •Источники времени
- •Соглашения POSIX
- •struct timespec { time_t tv_sec long tv_nsec
- •Текущее время
- •Операции задержки sleep(), usleep(), nanosleep()
- •sleep(), usleep(), nanosleep()
- •Тайм-аут. alarm(), signal(), pause()
- •Интервальный таймер
- •Интервальный таймер i8254
- •Примеры использования
- •Приложение – ISR (Interrupt Service Routine)
- •Сторожевой таймер (Watchdog Timer - WDT)
- •Часы реального времени (Real-Time Clock)
Абсолютное и относительное время
Универсальное координированное время UTS (Universal Time Coordinated). За начало отсчета UTC принимается 00:00:00 01 января 1070 года.
В компьютер текущее значение UTC вводится при инсталляции и загрузке операционной системы. В случае необходимости введенное значение может корректироваться вручную или автоматически от серверов по сетям связи с использованием протокола NTP (Network Time Protocol).
Абсолютное время – время, измеряемое относительно начального отсчета UTC
Относительное время – время, измеряемое относительно некоторого момента, заданной точки временной оси, например, момента запуска программы или формирования сигнала операционной системой.
По теме см. файлы
«РВС_31_short.doc», «Служба времени.pdf»
6. Время и таймеры v.01 |
1 |
|
Источники времени
|
|
Генератор тактовых импульсов |
|
|
|
Регистр процессора |
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||
|
|
|
|
шины процессора |
|
|
|
|
64 разряда (TSC) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Генератор |
|
|
|
Аппаратный |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
|
(1.1931816 МГц) |
|
|
таймер (i8254) |
|
0.1 -1 Кгц |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
Генератор |
|
Часы реального |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
|
часов РВ |
|
|
|
времени |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
Обработка |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
2 – 8192 Гц (Linux) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
прерываний |
|
А |
|
|
|
Тек. время |
||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Системные |
P |
|
|
|
Задержка |
||||||||||||||
(*) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
часы |
|
|
|
Уведомление |
||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
I |
|
|
|
|||||||||||||||||
|
(*) – «тик» системных часов |
|
|
Ядро ОС |
|
|
|
Период. событие |
|||||||||||||||||||||||||||||
|
|
t |
- разрешающая способность |
|
|
|
|
|
|
|
|
||||||||||||||||||||||||||
|
|
|
|
(период) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6. Время и таймеры 2020 v.01 |
2 |
|
Соглашения POSIX
•POSIX описывает множество базовых, системных сервисов, необходимых для функционирования прикладных программ и API (Application Programming Interface) для доступа к ним, специфицированного для языка C
Тик n |
а |
в |
Тик n+1 |
•Любые два (а и в) или более событий, происходящие между двумя тиками (Тик n, Тик n+1), считаются одновременными.
а |
Тик |
Реальное время события а «Компьютерное» время события а
•Временной интервал, истекший в момент между двумя тиками, округляется до большего значения. Заданный временной интервал после его отработки средствами всегда будет не меньше исходного значения.
6. Время и таймеры 2020 v.01 |
3 |
|
API
(Функции, документированные в стандарте POSIX)
Временной базис – условия, определенные для работы функции
CLOCK_REALTIME – подразумевается, что часы работают постоянно, аналогично нашим настенным или ручным часам. Значение времени таких часов можно корректировать . Событие, вызванное окончанием временного интервала некоторого таймера, «разбудит» процессор, если он находится в спящем режиме.
CLOCK_MONOTONIC – часы работают постоянно, без остановки даже
в случаях «спящего процессора», показания их корректировать невозможно.
CLOCK_SOFTTIME – часы активны только тогда, когда процессор не находится в спящем режиме. Например, если процессор в спящем режиме,
то таймер, работающий в этом базисе, не «разбудит» его, когда истечет заданный интервал. Когда такие часы активны, то их свойства аналогичны CLOCK_REALTIME.
6. Время и таймеры 2020 v.01 |
4 |
|
struct timespec { time_t tv_sec long tv_nsec
}
struct timeval { time_t tv_sec suseconds_t tv_usec
}
time_t, clock_t, suseconds_t, clockid_t обычно int или long
int.
6. Время и таймеры v.01 |
5 |
|
Текущее время
clock_getres() позволяет получить разрешающую способность системных часов (время между двумя последовательными тиками системных часов).
clock() возвращает количество тиков с момента запуска вызывающей программы.
time() позволяет получить текущее значение системных часов в секундах, истекшее с 1-го января 1970 года.
gettimeofday(), аналогично функции time(), позволяет получить текущее значение системных часов, истекшее с 1-го января 1970 года, но с точностью до микросекунды.
clock_gettime() позволяет получить значение текущего системного времени с точностью до наносекунды.
clock_settime() устанавливает значение системных часов с временным базисом id в значение, указанное в struct timespec.
6. Время и таймеры v.01 |
6 |
|
Операции задержки sleep(), usleep(), nanosleep()
Из-за дискретности системных часов и из-за многозадачности ОС точное выполнение требуемой задержки обеспечить невозможно:
•Вызов функции происходит асинхронно по отношению к последовательности тиков. Поэтому временной отсчет будет начинаться со следующего тика после момента вызова функции, и, следовательно, реальное время задержки будет увеличиваться. Такое увеличение происходит один раз в начале интервала задержки, поэтому, чтобы максимально снизить относительную погрешность, не следует рассчитывать на работу с короткими интервалами, особенно с интервалами, близкими к разрешающей способности системных часов.
•По истечении заданного интервала поток не продолжает работу сразу, а ставится в очередь потоков, готовых к выполнению. И сколько времени пройдет до момента его выхода из очереди зависит от алгоритма диспетчеризации и количества активных потоков в данный момент.
6. Время и таймеры v.01 |
7 |
|
sleep(), usleep(), nanosleep()
В случае возникновения сигнала, прерывающего работу функции, задержка не будет выдержана до конца.
#include <unistd.h>
unsigned int sleep( unsigned int seconds );
seconds – количество секунд, на которое следует задержать выполнение потока.
int usleep( useconds_t useconds );
useconds – количество микросекунд, на которое задерживается выполнение потока. Значение должно быть меньше 1000000.
#include <time.h>
int nanosleep( const struct timespec* rqtp, struct timespec* rmtp );
rqtp – указатель на структуру timespec, в которой задается требуемый интервал;
rmtp – NULL или указатель на структуру timespec, куда функция может записать длительность интервала, недоработанного из-за прерывания.
6. Время и таймеры v.01 |
8 |
|
Тайм-аут. alarm(), signal(), pause()
Тайм-аут - временной интервал, по истечении которого операционная система формирует сигнал. В данном случае таким сигналом является SIGALRM. Три функции, определенные стандартом POSIX 1003.1, с помощью которых обеспечивается выполнение тайм-аута.
#include <unistd.h>
unsigned int alarm( unsigned int seconds );
инициирует посылку сигнала SIGALRM через seconds. При seconds = 0 процесс ожидания сигнала сбрасывается, и функция возвращает число секунд, оставшееся до окончания заданного интервала.
6. Время и таймеры v.01 |
9 |
|
#include <signal.h>
void signal (int sig, void (* func)(int));
sig – номер (наименование) сигнала; в нашем случае (Пример 8) используется сигнал с номером 14 (SIGALRM);
func – имя функции-обработчика, которая будет вызвана при возникновении сигнала sig. Номер сигнала будет передан ей в качестве параметра.
По окончанию работы функции-обработчика поток, ожидающий сигнала, продолжит свое выполнение.
Функция-обработчик оформляется в виде: void func( int sig_no ){
...
}
Функция pause() задерживает выполнение потока до получения сигнала.
#include <unistd.h> int pause( void );
6. Время и таймеры v.01 |
10 |
|