Taimermehhanismid võimaldavad teil ajastada OS-i kernel, et see teavitaks rakendust, kui etteantud aeg on möödas. Tavaliselt kasutate neid, esitades kaks teavet. Esiteks peate määrama, kui palju aega peaks taimer enne teavitamist võtma. Teiseks peate ette valmistama tagasihelistamisfunktsiooni, mis toimib selle teate ilmumisel.

Traditsiooniline lähenemine taimeritele

Linuxi ja Unixi-põhiste süsteemide taimermehhanismid on arenenud erinevate vajaduste rahuldamiseks. Erinevad lähenemisviisid võivad aidata teil lahendada erinevat tüüpi probleeme. Siiski näete sageli selle esimest versiooni äratus () mehhanism veel kasutusel.

Äratusfunktsioon on lihtsaim viis taimeri kasutamiseks; siin on selle prototüüp:

allkirjastamataintäratus(allkirjastamataint sekundit);

Seda meetodit kasutades saate määrata aja ainult tervetes sekundites. Kui aeg saab täis, saadab operatsioonisüsteem SIGALRM signaali teie rakendusele. Taimeri aegumise töötlemiseks oma rakenduses peaksite määratlema ka tagasihelistamise funktsiooni.

Siin on näide signaali töötleja funktsioonist:

#sisaldama
#sisaldama
#sisaldama
#sisaldama

tühinetimer_callback(int signum)
{
aeg_t nüüd = aeg (NULL);
printf("Signaal %d kinni %li", signum, nüüd);
}

intpeamine()
{
signaal (SIGALRM, taimer_tagasihelistamine);
äratus (1);
magama (3);
tagasi0;
}

See kood tõstab a SIGALRM signaali pärast 1 teiseks. Kui soovite taimeri viivitust viie sekundini suurendada, helistage lihtsalt äratus (5) selle asemel. Taimeri peatamiseks sisestage väärtus 0: äratus (0).

Kui aeg on täis, ei käivitu kasutatav taimer perioodiliselt uuesti. Näiteks kui soovite veel sekundi edasi lükata, peaksite mehhanismi taaskäivitama uue kõnega äratus ().

Vaatamata kasutuslihtsusele on sellel meetodil mõned puudused:

  • Ainult üks taimer korraga.
  • Perioodilise taimeri tugi puudub.
  • Saate anda ajaperioodi ainult tervete sekundite kordades.
  • Pole võimalik teada, kui palju aega taimerile on jäänud.

Salvestage ülaltoodud näidiskood kui alarm.c. Millal koostate ja käivitate seda kutsub programm välja timer_callback funktsiooni ühe sekundi pärast. Seejärel ootab see ülejäänud kaks sekundit magama (3) rida, seejärel lõpetage.

$ gcc -o alarm alarm.c
$ aeg ./häire
Signaal 14 tabati numbril 1653490465
reaalne 0m1.004s
kasutaja 0m0.000s
sys 0m0.003s

Ajakäskluse kasutamise põhjus on kellaaegade nägemise võimalus. Aga kui tulemust vaadata, siis kogu jooksuaeg pole kolm sekundit. See on tingitud SIGALRM signaal alates äratus (1) kui esimene sekund on täis, samal ajal kui syscall põhjustatud unerežiimi (3) töötamisest. Kui see signaal saabub, katkestab see jaoks algatatud syscall magama (3).

Intervallitaimeri kasutamine

Intervallitaimeri mehhanism oli esmakordselt saadaval versioonis 4.2 BSD. See oli hiljem POSIXi poolt standarditud. Selle peamised eelised traditsioonilise ees äratus () Taimeripõhised meetodid on järgmised:

  • Pakub mikrosekundi eraldusvõimet.
  • See võimaldab aja mõõtmist täpsemalt juhtida kolme erineva režiimi kaudu.
  • Seda on võimalik üks kord seadistada ja perioodiliselt tööle panna.
  • On võimalik teada saada, kui kaua see igal hetkel kohal on.

Intervalltaimeri toimingute jaoks kasutatavad funktsioonide prototüübid on järgmised:

#sisaldama

intseadistus(int mis, konst struct itimerval *newValue, struct itimerval *oldValue);
intgetitimer(int mis, struct itimerval *value);

struktuuritimerval
{
struktuurajalineitInterval;// järgmine väärtus
struktuurajalineitValue;// praegune väärtus
};

struktuurajaline
{
pikk tv_sec;
pikk tv_usec;
};

Kui soovite seadistada intervalltaimerit, peate kasutama itimerval struktuur. Peate edastama väärtuse, kasutades seda struktuuri teise argumendina seadistaja funktsiooni.

Näiteks intervalltaimeri, mis teavitab teie rakendust 1 sekundi ja seejärel iga 300 millisekundi järel, saab seadistada järgmiselt.

struktuuritimervaluus Taimer;
struktuuritimervalvanaTimer;

newTimer.itValue.tv_sec = 1;
newTimer.itValue.tv_usec = 0;

newTimer.itInterval.tv_sec = 0;
newTimer.itInterval.tv_usec = 300 * 1000;

setitimer (ITIMER_REAL, &newTimer, &oldTimer);

Kui intervalltaimer on enne uute väärtuste määramist aktiivne, kantakse selle väärtused muutujaaadressile itimerval funktsiooni kolmandale parameetrile antud tüüp.

Intervalltaimeri mehhanismiga saate seadistada kolme erinevat tüüpi taimerit. Määrake taimeri tüüp esimeses parameetris setitimer():

Taimeri tüüp Signaal Selgitus
ITIMER_REAAL SIGALRM Sõltumata rakendusele kulunud ajast, arvutatuna kogu kulunud aja kohta.
ITIMER_VIRTUAL SIGVTALRM Arvutatakse aja jooksul, mil rakendus töötab ainult kasutajarežiimis.
ITIMER_PROF SIGPROF Arvutatakse rakenduse poolt nii kasutaja- kui ka süsteemirežiimis kulutatud aja summa alusel.

Sellest tabelist näete, et ITIMER_REAAL tüüp saadab a SIGALRM signaal, täpselt nagu äratus () funktsiooni.

Kasutades intervalltaimerit ja äratus () samas rakenduses on segane. Kuigi saate järelejäänud aja kohta teistkordselt kontrollida gettimer(), pole mõtet neid samaaegselt kasutada.

Siin on näide signaali töötleja funktsiooni määratlemisest silumispäis:

#sisaldama
#sisaldama
#sisaldama
#sisaldama
#sisaldama
#sisaldama
#sisaldama
#sisaldama "./debug.h"

tühinetimer_callback(int signum)
{
struktuurajalinenüüd;
gettimeofday(&now, NULL);
printf("Signaal %d tabati %li.%03li ", signum, now.tv_sec, now.tv_usec / 1000);
}

intpeamine()
{
allkirjastamataint järelejäänud = 3;

struktuuritimervaluus_taimer;
struktuuritimervalvana_taimer;

new_timer.it_value.tv_sec = 1;
new_timer.it_value.tv_usec = 0;
new_timer.it_interval.tv_sec = 0;
new_timer.it_interval.tv_usec = 300 * 1000;

setitimer (ITIMER_REAL, &uus_taimer, &vana_taimer);
signaal (SIGALRM, taimer_tagasihelistamine);

samas (magama (jäänud) != 0)
{
kui (errno == EINTR)
debugf("signaal katkestas unerežiimi");
muidu
errorf("uneviga %s", strerror (errno));
}

tagasi0;
}

Ülaltoodud kood kasutab magama () funktsioon oodata kolm sekundit. Selle aja jooksul töötab intervallitaimer, esmalt ühe sekundi ja seejärel 300 millisekundilise intervalliga.

Parema mõistmise huvides salvestage ja koostage näidiskood koos nimega intervall.c:

$ gcc -o intervall intervall.c
$ aeg ./intervall
Signaal 14 tabati numbril 1653493614.325
silumine: unerežiim katkes signaali tõttu (põhiintervall.c: 36)
Signaal 14 tabati numbril 1653493614.625
silumine: unerežiim katkes signaali tõttu (põhiintervall.c: 36)
Signaal 14 tabati numbril 1653493614.925
silumine: unerežiim katkes signaali tõttu (põhiintervall.c: 36)
Signaal 14 tabati numbril 1653493615.225
silumine: unerežiim katkes signaali tõttu (põhiintervall.c: 36)
Signaal 14 tabati numbril 1653493615.525
...

Nagu näete pärast taimeri käitamist väljundist, kutsub see tagasihelistamisfunktsiooni iga 300 millisekundi järel.

Kuid pärast veidi pikemat ootamist märkate, et rakendus ei lõpe. See jätkab tagasihelistamise funktsiooni käivitamist iga 300 millisekundi järel. Kui suurendate intervalli väärtust millisekundites, näete, et rakendus lõpeb. Selle põhjuseks on seadme kasutusala magama () funktsiooni.

Taimerite kasutamise tähtsus Linuxis

Eriti reaalajas rakenduste puhul on taimeri mehhanism väga oluline. Seda lahendust kasutatakse ka jõudluse optimeerimiseks. Saate seda kasutada isegi oma rakenduse tööaja või latentsuse mõõtmiseks. Möödunud aja ja ajalise ülemineku sündmuste jälgimiseks on oluline kasutada taimermehhanisme.

Kuidas Linuxis allikast tarkvara kompileerida ja installida

Loe edasi

JagaSäutsJagaMeil

Seotud teemad

  • Programmeerimine
  • Programmeerimine
  • Linuxi näpunäited

Autori kohta

Fatih Küçükkarakurt (10 avaldatud artiklit)

Insener ja tarkvaraarendaja, kes on matemaatika ja tehnoloogia fänn. Talle on alati meeldinud arvutid, matemaatika ja füüsika. Ta on arendanud nii mängumootorite projekte kui ka masinõpet, tehisnärvivõrke ja lineaaralgebra teeke. Lisaks jätkab ta tööd masinõppe ja lineaarsete maatriksitega.

Veel Fatih Küçükkarakurtilt

Liituge meie uudiskirjaga

Liituge meie uudiskirjaga tehniliste näpunäidete, arvustuste, tasuta e-raamatute ja eksklusiivsete pakkumiste saamiseks!

Tellimiseks klõpsake siin