Механизми тајмера вам омогућавају да закажете језгро ОС-а да обавести апликацију када протекне унапред одређено време. Обично ћете их користити тако што ћете дати две информације. Прво, мораћете да наведете колико времена тајмер треба да траје пре него што обавести. Друго, мораћете да припремите функцију повратног позива која ће деловати када се то обавештење појави.

Традиционални приступ тајмерима

Механизми тајмера у системима заснованим на Линук-у и Уник-у су еволуирали да би задовољили различите потребе. Различити приступи могу вам помоћи да решите различите врсте проблема. Међутим, често ћете видети прву верзију алармни() механизам још увек у употреби.

Функција аларма је најједноставнији начин коришћења тајмера; ево његовог прототипа:

непотписанинталармни(непотписанинт секунди);

Користећи овај метод, можете одредити само време у целим секундама. Када време истекне, оперативни систем шаље СИГАЛРМ сигнал за вашу апликацију. За обраду истека тајмера у вашој апликацији, требало би да дефинишете и функцију повратног позива.

Ево примера функције руковаоца сигналом:

#укључити
#укључити
#укључити
#укључити

празнинатимер_цаллбацк(инт сигнум)
{
тиме_т сада = време (НУЛА);
принтф(„Сигнал %д ухваћен на %ли“, сигнум, сада);
}

интглавни()
{
сигнал (СИГАЛРМ, тимер_цаллбацк);
алармни(1);
спавати (3);
повратак0;
}

Овај код подиже а СИГАЛРМ сигнал после 1 друго. Ако желите да повећате кашњење тајмера на пет секунди, само позовите аларм (5) уместо тога. Да бисте зауставили тајмер, проследите вредност 0: аларм (0).

Када време истекне, тајмер који користите се неће повремено поново покретати. На пример, ако желите да одложите још једну секунду, требало би да поново покренете механизам са другим позивом на алармни().

Упркос једноставности употребе, ова метода има неке недостатке:

  • Само један по један тајмер.
  • Нема подршке за периодични тајмер.
  • Временски период можете дати само у више целих секунди.
  • Нема начина да знате колико је времена остало на тајмеру.

Сачувајте горњи пример кода као аларм.ц. Када компајлираш и покренеш то, програм ће позвати тимер_цаллбацк функционише након једне секунде. Затим ће сачекати преостале две секунде због спавати (3) линију, а затим прекинути.

$ гцц -о аларм аларм.ц
$ време ./аларм
Сигнал 14 ухваћен на 1653490465
реал 0м1.004с
корисник 0м0.000с
сис 0м0.003с

Разлог за коришћење команде за време је могућност да видите времена. Али ако погледате резултат, укупно време рада није три секунде. Ово је због СИГАЛРМ сигнал из аларм (1) када је прва секунда истекла, док је сисцалл узроковано покретањем функције спавања (3). Када овај сигнал стигне, он прекида системски позив покренут за спавати (3).

Коришћење интервалног тајмера

Механизам интервалног тајмера је први пут био доступан у верзији 4.2 БСД. Било је касније стандардизован од стране ПОСИКС-а. Његове главне предности у односу на традиционалне алармни() Методе базиране на тајмеру су:

  • Обезбеђује резолуцију у микросекундама.
  • Омогућава детаљнију контролу мерења времена у три различита режима.
  • Могуће га је подесити једном и учинити да ради периодично.
  • Могуће је сазнати колико дуго је присутан у сваком тренутку.

Прототипови функција који се користе за операције интервалног тајмера су следећи:

#укључити

интсетитимер(инт која, конст струцт итимервал *невВалуе, струцт итимервал *олдВалуе);
интгетитимер(инт који, струцт итимервал *валуе);

струцтитимервал
{
струцттимевалитИнтервал;// следећа вредност
струцттимевалитВалуе;// Тренутна вредност
};

струцттимевал
{
дугачак тв_сец;
дугачак тв_усец;
};

Ако желите да подесите интервални тајмер, мораћете да користите итимервал струцт. Мораћете да проследите вредност користећи ову структуру као други аргумент у сеттимер функција.

На пример, интервални тајмер који ће обавестити вашу апликацију на 1 секунду, а затим сваких 300 милисекунди може се подесити на следећи начин:

струцтитимервалневТимер;
струцтитимервалСтарина;

невТимер.итВалуе.тв_сец = 1;
невТимер.итВалуе.тв_усец = 0;

невТимер.итИнтервал.тв_сец = 0;
невТимер.итИнтервал.тв_усец = 300 * 1000;

сетитимер (ИТИМЕР_РЕАЛ, &невТимер, &олдТимер);

Ако је активан интервални тајмер пре него што се нове вредности поставе, његове вредности се преносе на адресу променљиве итимервал тип дат трећем параметру функције.

Можете подесити три различита типа тајмера са механизмом интервалног тајмера. Наведите тип тајмера у првом параметру сетитимер():

Тип тајмера Сигнал Објашњење
ИТИМЕР_РЕАЛ СИГАЛРМ Независно од времена које је апликација потрошила, рачунато на укупно протекло време.
ИТИМЕР_ВИРТУАЛ СИГВТАЛРМ Израчунато током времена када апликација ради само у корисничком режиму.
ИТИМЕР_ПРОФ СИГПРОФ Израчунава се преко збира времена које је апликација провела у корисничком и системском режиму.

Из ове табеле можете видети да је ИТИМЕР_РЕАЛ тип шаље а СИГАЛРМ сигнал, баш као и алармни() функција.

Коришћење интервалног тајмера и алармни() у истој апликацији ће бити збуњујуће. Иако можете још једном проверити преостало време са геттимер(), нема смисла користити их истовремено.

Ево примера дефинисања функције руковаоца сигналом помоћу заглавље за отклањање грешака:

#укључити
#укључити
#укључити
#укључити
#укључити
#укључити
#укључити
#укључити "./дебуг.х"

празнинатимер_цаллбацк(инт сигнум)
{
струцттимевалСада;
геттимеофдаи(&сада, НУЛА);
принтф(„Сигнал %д је ухваћен на %ли.%03ли ", сигнум, нов.тв_сец, нов.тв_усец / 1000);
}

интглавни()
{
непотписанинт преостали = 3;

струцтитимервалнев_тимер;
струцтитимервалСтарина;

нев_тимер.ит_валуе.тв_сец = 1;
нев_тимер.ит_валуе.тв_усец = 0;
нев_тимер.ит_интервал.тв_сец = 0;
нев_тимер.ит_интервал.тв_усец = 300 * 1000;

сетитимер (ИТИМЕР_РЕАЛ, &нев_тимер, &олд_тимер);
сигнал (СИГАЛРМ, тимер_цаллбацк);

док (спавати (преостало) != 0)
{
ако (еррно == ЕИНТР)
дебугф("Спавање прекинуто сигналом");
друго
еррорф("грешка спавања %с", стреррор (еррно));
}

повратак0;
}

Горњи код користи спавај() функција да сачека три секунде. За то време ради интервални тајмер, прво на једну секунду, а затим на интервал од 300 милисекунди.

За боље разумевање, сачувајте и компајлирајте узорак кода са именом интервал.ц:

$ гцц -о интервал интервала.ц
$ време ./интервал
Сигнал 14 ухваћен на 1653493614.325
отклањање грешака: спавање прекинуто сигналом (главни интервал.ц: 36)
Сигнал 14 ухваћен на 1653493614.625
отклањање грешака: спавање прекинуто сигналом (главни интервал.ц: 36)
Сигнал 14 ухваћен на 1653493614.925
отклањање грешака: спавање прекинуто сигналом (главни интервал.ц: 36)
Сигнал 14 ухваћен на 1653493615.225
отклањање грешака: спавање прекинуто сигналом (главни интервал.ц: 36)
Сигнал 14 ухваћен на 1653493615.525
...

Као што можете видети из излаза након што се тајмер покрене, он позива функцију повратног позива сваких 300 милисекунди.

Међутим, након мало дужег чекања, приметићете да се апликација не прекида. Наставља да покреће функцију повратног позива сваких 300 милисекунди. Ако повећате вредност интервала у милисекундама, видећете да се апликација завршава. То је због области употребе спавај() функција.

Важност коришћења тајмера у Линуку

Посебно за апликације у реалном времену, механизам тајмера је од велике важности. Ово је такође решење које се користи за оптимизацију перформанси. Можете га чак користити за мерење времена непрекидног рада или кашњења у вашој апликацији. Важно је користити механизме тајмера да бисте пратили протекло време и догађаје временске транзиције.

Како компајлирати и инсталирати софтвер из извора у Линуку

Реад Нект

ОбјавиТвеетОбјавиЕмаил

Повезане теме

  • Програмирање
  • Програмирање
  • Линук савети

О аутору

Фатих Куцуккаракурт (Објављено 10 чланака)

Инжењер и програмер софтвера који је љубитељ математике и технологије. Одувек је волео компјутере, математику и физику. Развио је пројекте мотора за игре, као и машинско учење, вештачке неуронске мреже и библиотеке линеарне алгебре. Штавише, наставља да ради на машинском учењу и линеарним матрицама.

Више од Фатих Куцуккаракурт

Претплатите се на наш билтен

Придружите се нашем билтену за техничке савете, рецензије, бесплатне е-књиге и ексклузивне понуде!

Кликните овде да бисте се претплатили