Letysite.ru

IT Новости с интернет пространства
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Linux timer create

Linux timer create

int timer_create(clockid_t clockid, struct sigevent *restrict evp,
timer_t *restrict
timerid);

DESCRIPTION

The timer_create() function shall create a per-process timer using the specified clock, clock_id, as the timing base. The timer_create() function shall return, in the location referenced by timerid, a timer ID of type timer_t used to identify the timer in timer requests. This timer ID shall be unique within the calling process until the timer is deleted. The particular clock, clock_id, is defined in . The timer whose ID is returned shall be in a disarmed state upon return from timer_create().

The evp argument, if non-NULL, points to a sigevent structure. This structure, allocated by the application, defines the asynchronous notification to occur as specified in Signal Generation and Delivery when the timer expires. If the evp argument is NULL, the effect is as if the evp argument pointed to a sigevent structure with the sigev_notify member having the value SIGEV_SIGNAL, the sigev_signo having a default signal number, and the sigev_value member having the value of the timer ID.

Each implementation shall define a set of clocks that can be used as timing bases for per-process timers. All implementations shall support a clock_id of CLOCK_REALTIME. If the Monotonic Clock option is supported, implementations shall support a clock_id of CLOCK_MONOTONIC.

Per-process timers shall not be inherited by a child process across a fork() and shall be disarmed and deleted by an exec.

If _POSIX_CPUTIME is defined, implementations shall support clock_id values representing the CPU-time clock of the calling process.

If _POSIX_THREAD_CPUTIME is defined, implementations shall support clock_id values representing the CPU-time clock of the calling thread.

It is implementation-defined whether a timer_create() function will succeed if the value defined by clock_id corresponds to the CPU-time clock of a process or thread different from the process or thread invoking the function.

RETURN VALUE

If the call succeeds, timer_create() shall return zero and update the location referenced by timerid to a timer_t, which can be passed to the per-process timer calls. If an error occurs, the function shall return a value of -1 and set errno to indicate the error. The value of timerid is undefined if an error occurs.

ERRORS

The timer_create() function shall fail if: EAGAIN The system lacks sufficient signal queuing resources to honor the request. EAGAIN The calling process has already created all of the timers it is allowed by this implementation. EINVAL The specified clock ID is not defined. ENOTSUP The implementation does not support the creation of a timer attached to the CPU-time clock that is specified by clock_id and associated with a process or thread different from the process or thread invoking timer_create().

The following sections are informative.

EXAMPLES


APPLICATION USAGE


RATIONALE


Periodic Timer Overrun and Resource Allocation

The specified timer facilities may deliver realtime signals (that is, queued signals) on implementations that support this option. Since realtime applications cannot afford to lose notifications of asynchronous events, like timer expirations or asynchronous I/O completions, it must be possible to ensure that sufficient resources exist to deliver the signal when the event occurs. In general, this is not a difficulty because there is a one-to-one correspondence between a request and a subsequent signal generation. If the request cannot allocate the signal delivery resources, it can fail the call with an [EAGAIN] error.

Periodic timers are a special case. A single request can generate an unspecified number of signals. This is not a problem if the requesting process can service the signals as fast as they are generated, thus making the signal delivery resources available for delivery of subsequent periodic timer expiration signals. But, in general, this cannot be assured-processing of periodic timer signals may «overrun»; that is, subsequent periodic timer expirations may occur before the currently pending signal has been delivered.

Also, for signals, according to the POSIX.1-1990 standard, if subsequent occurrences of a pending signal are generated, it is implementation-defined whether a signal is delivered for each occurrence. This is not adequate for some realtime applications. So a mechanism is required to allow applications to detect how many timer expirations were delayed without requiring an indefinite amount of system resources to store the delayed expirations.

The specified facilities provide for an overrun count. The overrun count is defined as the number of extra timer expirations that occurred between the time a timer expiration signal is generated and the time the signal is delivered. The signal-catching function, if it is concerned with overruns, can retrieve this count on entry. With this method, a periodic timer only needs one «signal queuing resource» that can be allocated at the time of the timer_create() function call.

A function is defined to retrieve the overrun count so that an application need not allocate static storage to contain the count, and an implementation need not update this storage asynchronously on timer expirations. But, for some high-frequency periodic applications, the overhead of an additional system call on each timer expiration may be prohibitive. The functions, as defined, permit an implementation to maintain the overrun count in user space, associated with the timerid. The timer_getoverrun() function can then be implemented as a macro that uses the timerid argument (which may just be a pointer to a user space structure containing the counter) to locate the overrun count with no system call overhead. Other implementations, less concerned with this class of applications, can avoid the asynchronous update of user space by maintaining the count in a system structure at the cost of the extra system call to obtain it.

Timer Expiration Signal Parameters

The Realtime Signals Extension option supports an application-specific datum that is delivered to the extended signal handler. This value is explicitly specified by the application, along with the signal number to be delivered, in a sigevent structure. The type of the application-defined value can be either an integer constant or a pointer. This explicit specification of the value, as opposed to always sending the timer ID, was selected based on existing practice.

It is common practice for realtime applications (on non-POSIX systems or realtime extended POSIX systems) to use the parameters of event handlers as the case label of a switch statement or as a pointer to an application-defined data structure. Since timer_ids are dynamically allocated by the timer_create() function, they can be used for neither of these functions without additional application overhead in the signal handler; for example, to search an array of saved timer IDs to associate the ID with a constant or application data structure.

FUTURE DIRECTIONS


SEE ALSO

clock_getres() , timer_delete() , timer_getoverrun() , the Base Definitions volume of IEEE Std 1003.1-2001,

Таймер разрешения 1ms под linux рекомендуемый способ

Мне нужен таймер с разрешением 1ms под linux. Он используется для увеличения значения таймера, которое, в свою очередь, используется для просмотра различных событий. POSIX timerfd_create не является опцией из-за требования glibc. Я попробовал timer_create и timer_settimer, но лучшее, что я получаю от них, — это разрешение 10ms, меньшие значения по умолчанию имеют разрешение 10ms. Getittimer и setitimer имеют разрешение 10 мс в соответствии с manpage.

единственный способ сделать этот таймер я могу в настоящее время думать о том, чтобы использовать clock_gettime с CLOCK_MONOTONIC в моем основном цикле тест, если ms прошел, и если да, то увеличить счетчик (а затем проверить, должны ли различные события срабатывать).

есть ли лучший способ сделать это, чем постоянно запрос в главном цикле? Каково рекомендуемое решение этой проблемы?

язык, который я использую, — это простой старый c

Читать еще:  Оптимизировать pdf онлайн

обновление
Я использую ядро 2.6.26. Я знаю, ты можешь. пусть он прерывается на 1 кГц, и функции POSIX timer_* затем могут быть запрограммированы до 1 мс, но это кажется ненадежным, и я не хочу использовать это, потому что ему может понадобиться новое ядро в некоторых системах. Некоторые фондовые ядра, похоже, все еще настроены на 100Hz. И мне нужно это обнаружить. Приложение может быть запущено на чем-то другом, чем моя система 🙂

Я не могу спать в течение 1 мс, потому что могут быть сетевые события, на которые я должен реагировать.

Как Я решен он Поскольку это не так важно, я просто заявил, что глобальный таймер имеет разрешение 100 мс. Все события, использующие собственный таймер, должны установить не менее 100 мс для истечения срока действия таймера. Мне было более или менее интересно, будет ли лучший способ, отсюда и вопрос.

почему я принял ответ Я думаю, что ответ от freespace лучше всего описывает, почему это невозможно без системы Linux в реальном времени.

12 ответов

опрос в основном цикле также не является ответом — ваш процесс может не получить много времени процессора, поэтому пройдет более 10 мс, прежде чем ваш код будет запущен, Что делает его спорным.

10ms — это стандартное разрешение таймера для большинства не -операционные системы в реальном времени (RTOS). Но это спорно в не-RTOS-поведение планировщика и диспетчера будет сильно влиять на то, как быстро вы можете реагировать на таймер истекает. Например, даже предположим, что у вас есть таймер разрешения sub 10ms, вы не можете ответить на таймер истекает, если ваш код не работает. Поскольку вы не можете предсказать, когда ваш код будет запущен, вы не можете точно ответить на истечение таймера.

есть, конечно, ядра linux в реальном времени, см. http://www.linuxdevices.com/articles/AT8073314981.html для списка. RTOS предлагает средства, с помощью которых вы можете получить мягкие или жесткие гарантии о том, когда ваш код будет работать. Это единственный способ надежно и точно ответьте к отметчикам времени expiring etc.

чтобы получить таймеры разрешения 1ms, сделайте то, что libevent делает.

Организуйте свои таймеры в мин-кучи, то есть верхняя часть кучи-это таймер с самым ранним (абсолютным) временем истечения (RB-дерево также будет работать, но с большими накладными расходами). Перед вызовом select() или epoll() в вашем основном цикле событий вычислите дельту в миллисекундах между временем истечения самого раннего таймера и сейчас. Используйте эту дельту в качестве таймаута для select() . select() и epoll() таймауты имеют разрешение 1ms.

у меня есть тест разрешения таймера, который использует механизм, описанный выше (но не libevent). Тест измеряет разницу между желаемым временем истечения таймера и его фактическим истечением таймеров 1ms, 5ms и 10ms:

тест выполнялся в режиме реального времени на ядре Fedora 13 2.6.34, наилучшая точность таймера 1ms была avg=22nsec stddev=29410nsec.

Я не уверен, что это лучшее решение, но вы можете подумать о написании небольшого модуля ядра, который использует таймеры ядра высокого разрешения для синхронизации. В принципе, вы создадите Файл Устройства, для которого чтение будет возвращаться только с интервалами 1ms.

пример такого подхода используется в АТС Asterisk через модуль ztdummy. Если вы Google для ztdummy вы можете найти код, который делает это.

Я думаю, вам будет сложно достичь точности 1 мс со стандартным Linux даже при постоянном запросе в основном цикле, потому что ядро не гарантирует, что ваше приложение будет получать CPU все время. Например, вас можно усыпить на десятки миллисекунд из-за упреждающей многозадачности, и вы мало что можете с этим поделать.

Если вы нацелены на платформу x86, вы должны проверить таймеры HPET. Это аппаратный таймер с большой точностью. Он должен поддерживаться вашим материнским кордом (сейчас все они поддерживают его), и ваше ядро также должно содержать драйвер для него. Я использовал его несколько раз без каких-либо проблем и смог достичь гораздо лучшего разрешения, чем 1ms.

вот некоторые документы и примеры:

Я, кажется, припоминаю становится ОК результаты с gettimeofday/usleep на основе опроса . я не нуждаясь 1000 таймеров в секунду или что-то, но мне были нужны хорошая точность со сроками для галочки мне нужна — мое приложение была миди контроллер драм-машина, и я, кажется, помню, как суб-миллисекундной точностью, что необходимо для драм-машины если вы не хотите, чтобы это звучало как очень плохой барабанщик (ЭСП. подсчет встроенных задержек MIDI) — iirc (это был 2005, поэтому моя память немного нечеткая) я был попадая в 200 микросекунд времени с usleep.

тем не менее, я больше не работал в системе. Если у вас есть контролируемая среда, Вы можете уйти с таким решением. Если в системе происходит больше (смотрите, как cron запускает updatedb и т. д. тогда все может развалиться.

вы работаете на ядре Linux 2.4?

гостевые операционные системы Linux сохраняют время подсчета прерываний таймера. Неочищенные 2.4 и более ранние ядра запрограммируйте таймер виртуальной системы на запрос прерывания часов на 100 Гц (100 прерывания в секунду). 2.6 ядра, с другой стороны, запрос прерывания при 1000Hz-в десять раз чаще. Некоторые 2.4 ядер измененный поставщиками распределение содержать 2.6 особенности запрос 1000Гц прерываний, или в некоторых случаи, прерывания по другим ставкам, такие как как 512Hz.

есть патч ktimer для ядра linux:

сначала получите источник ядра и скомпилируйте его с скорректированным параметром HZ.

  • если HZ=1000 , таймер прерывает 1000 раз в секунду. Это нормально использовать HZ=1000 для машины i386.
  • на встроенной машине Гц может быть ограничен 100 или 200.

для хорошей работы опция PREEMPT_KERNEL должна быть включена. Есть ядра, которые не поддерживают эту опцию должным образом. Вы можете проверить их испытующий.

последние ядра, т. е. 2.6.35.10, поддерживают параметры NO_HZ, которые превращаются на динамических ТИКах. Это означает, что не будет никаких тиков таймера, когда в режиме ожидания, но в указанный момент будет сгенерирован ТИК таймера.

существует патч RT для ядра, но аппаратная поддержка очень ограничена.

вообще RTAI все разрешение убийцы к вашей проблеме, но свое аппаратная поддержка очень ограничена. Однако, хорошие регуляторы CNC, как emc2, используйте RTAI для их синхронизации, возможно, 5000 Гц, но это может быть тяжелая работа, чтобы установить его.

Если вы можете, вы можете добавить оборудование для генерации импульсов. Это сделало бы система, которая может быть адаптирована к любой версии ОС.

можете ли вы, по крайней мере, использовать nanosleep в своем цикле для сна в течение 1 мс? Или это дело glibc?

обновление: неважно, я вижу с man-страницы «это может занять до 10 мс дольше, чем указано, пока процесс не станет снова запускаемым»

вам не нужен RTOS для простого приложения в реальном времени. Все современные процессоры имеют таймеры общего назначения. Получите техническое описание для любого целевого процессора, над которым вы работаете. Посмотрите в источнике ядра, в каталоге arch вы найдете конкретный источник процессора, как обрабатывать эти таймеры.

есть два подхода, которые вы можете взять с собой:

1) ваше приложение работает только на вашем компьютере состояния, и ничего больше. Linux-это просто «загрузчик.» Создайте объект ядра, который устанавливает символьное устройство. При вставке в ядро настройте таймер GP для непрерывного запуска. Ты знаешь, на какой частоте он работает. Теперь, в ядре, явно отключите своего сторожевого пса. Теперь отключите прерывания (аппаратное и программное обеспечение) на ядре Linux с одним процессором, вызов spin_lock () выполнит это (никогда не отпускайте его.) Процессор ваш. Цикл Busy, проверяющий значение GPT до тех пор, пока не пройдет требуемое число тиков, когда они установили значение для следующего таймаута и введите цикл обработки. Просто убедитесь, что время пакета для вашего кода меньше 1ms

2) 2-й вариант. Это предполагает, что вы используете упреждающее ядро Linux. Настройте неиспользуемый GPT вдоль вашей запущенной ОС. Теперь настройте прерывание, чтобы запустить некоторый настраиваемый запас, прежде чем произойдет тайм-аут 1ms (скажем, 50-75 uSec.) Когда прерывание срабатывает, вы немедленно отключите прерывания и вращение, ожидая появления окна 1ms, а затем введите ваш государственный компьютер и последующее включение прерываний на вашем переждать. Это объясняет тот факт, что вы сотрудничаете с другими вещами в ядре, которые отключают прерывания. Это предполагает, что нет никакой другой активности ядра, которая блокирует прерывания в течение длительного времени (более 100us.) Теперь вы можете измерить точность вашего события стрельбы и сделать окно больше, пока оно не удовлетворит ваши потребности.

Читать еще:  Apache скачать linux

Если вместо этого вы пытаетесь узнать, как работает RTOS. или если вы попытка решить проблему контроля с более чем одной ответственностью в режиме реального времени. затем используйте RTOS.

Как насчет использования устройства» /dev/rtc0 «(или» /dev/rtc») и связанного с ним интерфейса ioctl ()? Я думаю, что он предлагает точный счетчик таймера. Не возможно установить тариф как раз к 1 мс, а к близкому значению или 1/1024сек (1024хз), или к более высокой частоте, как 8192хз.

“Tea Time” – это простой таймер для рабочего стола Ubuntu

Joshua Kormik

Read more posts by this author.

Joshua Kormik


В поиске простого приложения-таймера для Ubuntu? Больше искать не придется, так как эта милая кроха по имени “Tea Time” вас точно устроит.

“Tea Time” будет всегда к месту. Представьте, что вы поставили пиццу в духовку или хотите выделить промежуток времени для учебы, а может быть решили правильно заварить какой-нибудь элитный чай – во всех этих случаях без хорошего таймера не обойтись.

Невероятно простое приложение. “Tea Time” позволяет быстро создавать и запускать/останавливать таймеры, которые можно выставлять на любые периоды времени.

Устанавливайте небольшие напоминалки как и когда хотите.

Иной способ делать дела

Приложения таймеры вещь не уникальная. Доступно множество апплетов индикаторов с ориентацией на время.

Но вряд ли вам захочется, чтобы ваш правый верхний угол экрана был забит иконками, требующими внимания. В этом и отличие “Tea Time” от, скажем, Indicator-Remindor.

Как использовать “Tea Time”

Сразу после установки вы можете создавать таймеры с помощью приложения, давать им названия и выставлять длительность.

Как только готовы запустить таймер, выбираете его в окне приложения и затем нажимаете на “Strat Timer” («начать отсчет»). После запуска таймера приложение минимизируется, а отсчет отображается на иконке приложения, чтобы вам было удобно следить за ним.

Звук колокольчика оповестит вас о завершении отсчета, и вы будете уверены, что пиццу можно доставать, чай наливать, а вашему хомячку уже хватить бегать в шарике. Есть оповещения для рабочего стола.

Со своей работой приложение справляется идеально – может и нет всяких свистулек, но зато, какая форма!

“Tea Time” бесплатное и оупенсорсное приложение. Оно невероятно легковесно (состоит всего из пары сотен строк на Python). На Ubuntu ее можно установить, проследовав инструкциям чуть ниже.

Было бы интересно увидеть адоптацию от умельцев иконки в виде чего-то вроде «кухонного таймера». Возможно, в виде яйца, а не базового значка будильника.

Кому-то может быть важно, что у приложения нет горячих клавиш.

Установка “Tea Timer” на Ubuntu 16.04 LTS +

Для того чтобы установить этот простой таймер на Ubuntu 16.04 и выше, откройте терминал и введите следующие команды:

После установки загляните в Unity Dash, найдите программу и наслаждайтесь.

Хотите версию для командной строки?

Если вы из тех пользователей, которые любят запасаться сторонними приложениями и внешними PPA, в этом нет нужды. Есть уйма способов запустить отсчет в командной строке.

Инструменты программирования в ядре: Часть 69. Таймеры ядра

Нам осталось рассмотреть таймерные функции — последний (из 3-х ранее названных) класс задач, связанных с отслеживанием времени. Функциональность таймера существенно шире и сложнее с точки зрения реализации, чем просто выжидание некоторого интервала времени, о чём рассказывалось в предыдущей статье. Основной задачей таймера является асинхронное возбуждение в указанный момент времени в будущем некоторого, заранее предписанного ему действия.

Абсолютное время

Ядро предоставляет драйверам API для работы с таймерами, так как в системе параллельно может существовать множество экземпляров таймеров. В файле содержится структура и ряд функций для декларации, регистрации и удаления таймеров ядра:

  • expires — значение jiffies , наступления которого таймер ожидает для срабатывания (абсолютное время);
  • function — указатель на функцию, которая вызывается при срабатывании с data в качестве аргумента;
  • data — этот параметр чаще всего содержит преобразованный указатель на структуру.

Функция таймера в ядре выполняется в контексте прерывания, если конкретно то в контексте обработчика прерывания системного таймера, но не в контексте процесса! Что накладывает на неё дополнительные ограничения:

  1. для данной функции запрещён доступ к пользовательскому пространству, так как из-за отсутствия контекста процесса, невозможно определить путь к пользовательскому пространству, связанному с любым определённым процессом;
  2. указатель current не имеет смысла и не может быть использован, так как соответствующий код не имеет связи с процессом, который был прерван;
  3. не может быть выполнен переход в блокированное состояние и переключение контекста.

Код в контексте прерывания не может вызывать schedule() или какую-то из форм wait_event() или любые другие функции, которые могли бы перевести его в пассивное состояние. Также нельзя использовать семафоры и им подобные примитивы синхронизации, которые могут переключить выполнение в пассивное состояние.

Код ядра может понять, работает ли он в контексте прерывания, используя макрос in_interrupt() .

Таймеры высокого разрешения

Таймеры высокого разрешения появились, начиная с версии ядра 2.6.16, а структуры представления времени для них определены в файле . Их поддержка присутствует только в архитектурах, поддерживающих аппаратные таймеры высокого разрешения. Также для них определяется новый временной тип данных ktime_t — временной интервал в наносекундном выражении, и его представления сильно отличаются в зависимости от архитектуры. Здесь же определяются множество функций для установки значений и преобразований представлений времени (многие из них определены как макросы, но ниже показаны как прототипы):

Сами операции с таймерами высокого разрешения определены в файле в структуре, напоминающей модель таймеров реального времени, вводимую для пространства пользователя стандартом POSIX 1003b:

Единственным определяемым пользователем полем этой структуры является функция реакции function , прототип которой приведён ниже:

Параметр which_clock типа clockid_t , относится к области стандарта POSIX и называется в нём временным базисом (тип задатчика времени): какую шкалу времени использовать из общего числа определённых в . Ниже перечислены возможные значения, часть из которых заимствована из POSIX, а другие расширяют существующие определения.

  • CLOCK_REALTIME — системные часы со всеми их плюсами и минусами. Могут быть переведены вперёд или назад, в этой шкале могут попадаться «вставные секунды», предназначенные для корректировки неточностей представления периода системного тика. Эта шкала времени чаще всего и используется в таймерах.
  • CLOCK_MONOTONIC — подобны CLOCK_REALTIME , но отличаются тем, что, представляют собой постоянно увеличивающийся счётчик, и поэтому не могут быть изменены при переводе времени. Обычно это счётчик времени от загрузки системы.
  • CLOCK_PROCESS_CPUTIME_ID — возвращает время, затраченное процессором на работу только с данным приложением в независимости от других задач системы. Именно этот базис чаще всего используется для пользовательского адресного пространства.
  • CLOCK_THREAD_CPUTIME_ID — похоже на CLOCK_PROCESS_CPUTIME_ID , но отсчитывается время, затрачиваемое только на один текущий поток.
  • CLOCK_MONOTONIC_RAW — то же что и CLOCK_MONOTONIC , но в отличии от первого не подвержен изменению через сетевой протокол точного времени NTP.

Последние два базиса CLOCK_REALTIME_COARSE и CLOCK_MONOTONIC_COARSE были добавлены в 2009 году, и, как утверждается их авторами, они могут обеспечить гранулярность шкалы мельче, чем предыдущие базисы. Работу с различными базисами времени обеспечивают в пространстве пользователя не очень известные API вида clock_*() (clock_gettext() , clock_nanosleep() , и т.д.). Разрешение каждого из базисов можно получить вызовом:

Для наших примеров таймеров можно использовать базисы CLOCK_REALTIME или CLOCK_MONOTONIC . В модуле htick.c представлен пример использования таймеров высокого разрешения в периодическом режиме, хотя он и не раскрывает все возможности базисов высокого расширения. Полный код примера можно найти в архиве time.tgz в разделе «Материалы для скачивания».

Листинг 1. Пример использования системных часов в модуле ядра

Запустим наш модуль и изучим полученные результаты:

Часы реального времени (RTC)

Часы реального времени — это исключительно аппаратное расширение, принципиально зависящее от аппаратной платформы, на которой установлена ОС Linux. Это одно из расширений службы системных часов, поэтому оно может отсутствовать на некоторых архитектурах. Используя часы реального времени можно создать ещё одну независимую шкалу отсчётов времени, с которой можно связать измерения или асинхронную активацию действий.

Читать еще:  Оптимизация пдф онлайн

Убедиться в наличии такого расширения на используемой аппаратной платформе можно по присутствию интерфейса к таймеру часов реального времени в пространстве пользователя. Такой интерфейс предоставляется через функции ioctl() драйвера присутствующего в системе устройства /dev/rtc:

В архитектуре Intel x86 устройство этого драйвера называется Real Time Clock (RTC). RTC предоставляет функцию для работы со 114-битовым значением в NVRAM. На входе этого устройства установлен осциллятор с частотой 32768 КГц, подсоединенный к энергонезависимой батарее. Некоторые дискретные модели RTC имеют встроенные осциллятор и батарею, тогда как другие RTC встраиваются прямо в контроллер периферийной шины (например, южный мост) чипсета процессора. RTC возвращает не только время суток, но, также является и программируемым таймером, способным посылать системные прерывания (IRQ 8). Частота прерываний варьируется от 2 до 8192 Гц. Также RTC может посылать прерывания ежедневно, наподобие будильника. Все определения находятся в файле :

Ниже перечислены некоторые важные коды команд ioctl() :

В листинге 2 приведён пример использования RTC из пользовательской программы для считывания абсолютного значения времени (полный код примера можно найти в архиве time.tgz в разделе «Материалы для скачивания»):

Листинг 2. Пример использования часов реального времени из пространства пользователя (файл rtcr.c)

Результат запуска данного примера:

В ещё одном примере в листинге 3 показывается, как часы RTC могут использоваться как независимый источник времени в программе, генерирующей периодические прерывания с высокой (значительно выше системного таймера) частотой следования:

Листинг 3. Использование часов реального времени в качестве независимого источника времени (файл rtprd.c)

В этом примере прерывания RTC прерывают блокирующую операцию read() гораздо чаще периода системного тика. В листинге 3 наглядно демонстрируется запуск процесса без перевода (что делается по умолчанию) в реал-тайм диспетчирование (ключ -n), когда дисперсия временной латентности возрастает сразу на 2 порядка (эти эффекты вытесняющего диспетчирования, должны всегда приниматься во внимание при планировании измерений временных интервалов):

Запустим данный пример и рассмотрим полученные результаты:

Код пользовательского процесса, представленный в листинге 3, проясняет, как и на каких интервалах могут использоваться часы реального времени. Точный способ, используемый для считывания RTC-времени в ядре, не скрывается никакими обёртками и зависит от использованного оборудования RTC. Для наиболее используемого чипа Motorola 146818 (который в таком наименовании уже не производится и заменяется аналогами) соответствующие макросы и другую информацию можно найти в файле :

А определения, необходимые для понимания происходящего, находятся в файле :

Это значит, что в порт 0х70 записывается номер требуемого параметра, а по порту 0х71 считывается/записывается требуемое значение — так традиционно организуется обмен данными в памяти CMOS.

Примечание: Часы RTC, как уже было отмечено, синхронизируются от другого кварцевого резонатора, чем системный таймер. А, поскольку никакой резонатор не может иметь абсолютно точную частоту, то на расхождении времени RTC и системного может быть построена идентификация конкретного экземпляра системной платы, например, для целей привязки к оборудованию и защиты от копирования.

Заключение

В этой части было рассмотрен последний, и самый сложный механизм определения временных интервалов — таймеры. На этом завершается обзор службы времени в Linux, хотя в ней сокрыто ещё множество любопытных вещей.

8.13. Функция setitimer(): задание интервальных таймеров

8.13. Функция setitimer(): задание интервальных таймеров

Функция setitimer() является обобщением системного вызова alarm() . Она планирует доставку сигнала по истечении заданного промежутка времени.

С помощью функции setitimer() можно создавать таймеры трех типов.

? ITIMER_REAL . По истечении указанного времени процессу посылается сигнал SIGALRM .

? ITIMER_VIRTUAL . После того как процесс отработал требуемое время, ему посылается сигнал SIGVTALRM . Время, когда процесс не выполнялся (работало ядро или другой процесс), не учитывается.

? ITIMER_PROF . По истечении указанного времени процессу посылается сигнал SIGPROF . Учитывается время выполнения самого процесса, а также запускаемых в нем системных вызовов.

Код таймера задается в первом аргументе функции setitimer() . Второй аргумент — это указатель на структуру типа itimerval , содержащую параметры таймера. Третий аргумент либо равен NULL , либо является указателем на другую структуру itimerval , куда будут записаны прежние параметры таймера.

В структуре itimerval два поля.

? it_value . Здесь находится структура типа timeval , где записано время отправки сигнала. Если это поле равно нулю, таймер отменяется.

? it_interval . Это еще одна структура timeval , определяющая, что произойдет после отправки первого сигнала. Если она равна нулю, таймер будет отменен. В противном случае здесь записан интервал генерирования сигналов.

Структура timeval была описана в разделе 8.7. «Функция gettimeofday() : системные часы»

В листинге 8.11 показано, как с помощью функции setitimer() отслеживать выполнение программы. Таймер настроен на интервал 250 мс, по истечении которого генерируется сигнал SIGVTALRM .

Листинг 8.11. (itimer.c) Пример создания таймера

void timer_handler(int signum) <

static int count = 0;

printf(«timer expired %d times «, ++count);

struct sigaction sa;

struct itimerval timer;

/* Назначение функции timer_handler обработчиком сигнала

/* Таймер сработает через 250 миллисекунд. */

/* . и будет продолжать активизироваться каждые 250

/* Запуск виртуального таймера. Он подсчитывает фактическое

время работы процесса. */

/* Переход в бесконечный цикл. */

Похожие главы из других книг:

Использование таймеров

Использование таймеров Таймеры представлены с помощью структур timer_list, которая определена в файле
следующим образом.struct timer_list < struct list_head entry; /* таймеры хранятся в связанном списке */ unsigned long expires; /* время окончание срока ожидания в

Реализация таймеров

Реализация таймеров Ядро выполняет обработчики таймеров в контексте обработчика отложенного прерывания после завершения обработки прерывания таймера. Обработчик прерывания таймера вызывает функцию update_process_times(), которая в свою очередь вызывает функцию run_local_timers(),

Типы таймеров

Типы таймеров Таймер, работу которого мы только что обсудили, называют относительным таймером. Для такого таймера период ожидания задается относительно текущего времени. Если бы вы пожелали задержать выполнение вашего потока до 12 часов 4 минут 33 секунд EDT (Eastern Daylight Time —

Применение таймеров

Применение таймеров Изучив все красоты теории, давайте теперь переключим наше внимание на конкретные образцы кода, чтобы посмотреть, что можно сделать при помощи таймеров.Чтобы работать с таймером, вам потребуется:1. Создать объект типа «таймер».2. Выбрать схему

18.2. Использование таймеров

18.2. Использование таймеров Таймер — это простое средство для указаний определенной точки в будущем, в которой должно произойти некоторое событие. Вместо того чтобы циклически запрашивать текущее время и проводить лишние растраты циклов центрального процессора,

Программирование с помощью таймеров обратного вызова

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

Совет 37. Используйте accumulate или for_each для обобщения интервальных данных

Совет 37. Используйте accumulate или for_each для обобщения интервальных данных Иногда возникает необходимость свести целый интервал к одному числу или, в более общем случае, к одному объекту. Для стандартных задач обобщения существуют специальные алгоритмы. Так, алгоритм count

7.14. Создание таймеров

7.14. Создание таймеров Постановка задачи Требуется многократно выполнять определенную задачу после заданной задержки. Например, вы хотите обновлять вид на экране устройства каждую секунду, пока работает ваше

7.17. Выход из потоков и таймеров

7.17. Выход из потоков и таймеров Постановка задачи Требуется остановить поток или таймер либо не допустить его повторного

8.9. Функция mprotect(): задание прав доступа к памяти

8.9. Функция mprotect(): задание прав доступа к памяти В разделе 5.3, «Отображение файлов в памяти», рассказывалось о том, как осуществляется отображение файла в памяти. Вспомните, что третьим аргументом функции mmap() является битовое объединение флагов доступа: флаги PROT_READ, PROT_WRITE и

Использование таймеров

Использование таймеров Во многих случаях нужно выполнять какое-либо действие через равные промежутки времени. Это может понадобиться, например, для создания анимации с помощью сценариев ActionScript или для обновления информации, взятой с удаленного сервера. Для таких задач

Ссылка на основную публикацию
Adblock
detector