Ajastinmekanismien avulla voit ajastaa käyttöjärjestelmän ytimen ilmoittamaan sovellukselle, kun ennalta määritetty aika on kulunut. Käytät niitä yleensä antamalla kaksi tietoa. Ensin sinun on määritettävä, kuinka kauan ajastimen tulisi kestää ennen ilmoitusta. Toiseksi sinun on valmisteltava takaisinsoittotoiminto, joka toimii, kun kyseinen ilmoitus tapahtuu.

Perinteinen lähestymistapa ajastimiin

Linux- ja Unix-pohjaisten järjestelmien ajastinmekanismit ovat kehittyneet palvelemaan erilaisia ​​tarpeita. Erilaiset lähestymistavat voivat auttaa sinua ratkaisemaan erilaisia ​​ongelmia. Näet kuitenkin usein ensimmäisen version hälytys() mekanismi edelleen käytössä.

Hälytystoiminto on yksinkertaisin tapa käyttää ajastinta; tässä sen prototyyppi:

allekirjoittamatoninthälytys(allekirjoittamatonint sekuntia);

Tällä menetelmällä voit määrittää ajan vain kokonaisina sekunteina. Kun aika on lopussa, käyttöjärjestelmä lähettää SIGALRM signaali sovelluksellesi. Jotta voit käsitellä ajastimen vanhenemisen sovelluksessasi, sinun tulee myös määrittää takaisinsoittotoiminto.

instagram viewer

Tässä on esimerkki signaalinkäsittelytoiminnosta:

#sisältää
#sisältää
#sisältää
#sisältää

mitätöntimer_callback(int signum)
{
aika_t nyt = aika (TYHJÄ);
printf("Signaali %d kiinni %li", signum, nyt);
}

intpää()
{
signaali (SIGALRM, ajastin_takaisinsoitto);
hälytys(1);
nukkua(3);
palata0;
}

Tämä koodi herättää a SIGALRM signaali jälkeen 1 toinen. Jos haluat nostaa ajastimen viiveen viiteen sekuntiin, soita hälytys (5) sen sijaan. Pysäytä ajastin antamalla arvo 0: hälytys (0).

Kun aika on kulunut loppuun, käyttämäsi ajastin ei käynnisty uudelleen säännöllisesti. Jos esimerkiksi haluat viivyttää toisen sekunnin, sinun tulee käynnistää mekanismi uudelleen toisella kutsulla hälytys().

Helppokäyttöisyydestään huolimatta tällä menetelmällä on joitain haittoja:

  • Vain yksi ajastin kerrallaan.
  • Ei jaksollisen ajastimen tukea.
  • Voit antaa ajanjakson vain kokonaisten sekuntien kerrannaisina.
  • Ei voida tietää, kuinka paljon aikaa ajastimessa on jäljellä.

Tallenna yllä annettu esimerkkikoodi nimellä hälytys.c. Kun kokoat ja käytät sitä, ohjelma kutsuu timer_callback toiminto yhden sekunnin kuluttua. Se odottaa sitten jäljellä olevat kaksi sekuntia nukkua (3) rivi ja lopeta sitten.

$ gcc -o hälytyshälytys.c
$ aikaa ./hälytys
Signaali 14 kiinni numerosta 1653490465
todellinen 0m1.004s
käyttäjä 0m0.000s
sys 0m0.003s

Syy aikakomennon käyttöön on ajatusten näkeminen. Mutta jos katsot tulosta, kokonaisajoaika ei ole kolme sekuntia. Tämä johtuu siitä SIGALRM signaali lähteestä hälytys (1) kun ensimmäinen sekunti on ylhäällä, kun taas syscall johtuu siitä, että unitoiminto (3) on käynnissä. Kun tämä signaali saapuu, se keskeyttää aloitetun syscall: n nukkua (3).

Intervalliajastimen käyttäminen

Intervalliajastinmekanismi oli ensimmäisen kerran saatavilla versiossa 4.2 BSD. Se oli myöhemmin POSIXin standardoima. Sen tärkeimmät edut perinteisiin verrattuna hälytys() perustuvat ajastinmenetelmät ovat:

  • Tarjoaa mikrosekunnin resoluution.
  • Sen avulla voidaan hallita ajan mittausta tarkemmin kolmessa eri tilassa.
  • Se on mahdollista asettaa kerran ja saada se toimimaan säännöllisesti.
  • On mahdollista selvittää, kuinka kauan se on läsnä kulloinkin.

Intervalliajastintoimintoihin käytetyt toimintoprototyypit ovat seuraavat:

#sisältää

intsettimer(int joka, konst struct itimerval *newValue, struct itimerval *oldValue);
intgetitimer(int joka, struct itimerval *arvo);

structitimerval
{
structajankohtainenitInterval;// seuraava arvo
structajankohtainenitValue;// nykyinen arvo
};

structajankohtainen
{
pitkä tv_sec;
pitkä tv_usec;
};

Jos haluat määrittää intervalliajastimen, sinun on käytettävä itimerval struct. Sinun on välitettävä arvo käyttämällä tätä rakennetta toisena argumenttina ajastin toiminto.

Esimerkiksi intervalliajastin, joka ilmoittaa hakemuksellesi 1 sekunnin ja sen jälkeen 300 millisekunnin välein, voidaan määrittää seuraavasti:

structitimervaluusi ajastin;
structitimervaloldtimer;

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);

Jos intervalliajastin on aktiivinen ennen uusien arvojen asettamista, sen arvot siirretään muuttujaosoitteeseen itimerval funktion kolmannelle parametrille annettu tyyppi.

Voit asettaa kolme erilaista ajastinta intervalliajastinmekanismilla. Määritä ajastimen tyyppi ensimmäisessä parametrissa setitimer():

Ajastimen tyyppi Signaali Selitys
ITIMER_REAL SIGALRM Riippumatta sovelluksen käyttämästä ajasta, laskettuna kuluneelta kokonaisajalta.
ITIMER_VIRTUAL SIGVTALRM Lasketaan ajalle, jolloin sovellus on käynnissä vain käyttäjätilassa.
ITIMER_PROF SIGPROF Lasketaan sovelluksen sekä käyttäjä- että järjestelmätilassa käyttämän ajan summasta.

Tästä taulukosta näet, että ITIMER_REAL tyyppi lähettää a SIGALRM signaali, aivan kuten hälytys() toiminto.

Käyttämällä intervalliajastinta ja hälytys() samassa sovelluksessa on hämmentävää. Vaikka voit tarkistaa jäljellä olevan ajan toisen kerran gettimer(), ei ole järkevää käyttää niitä samanaikaisesti.

Tässä on esimerkki signaalinkäsittelytoiminnon määrittämisestä virheenkorjausotsikko:

#sisältää
#sisältää
#sisältää
#sisältää
#sisältää
#sisältää
#sisältää
#sisältää "./debug.h"

mitätöntimer_callback(int signum)
{
structajankohtainennyt;
päivän aika (&nyt, TYHJÄ);
printf("Signaali %d kiinni %li.%03li ", signum, now.tv_sec, now.tv_usec / 1000);
}

intpää()
{
allekirjoittamatonint jäljellä = 3;

structitimervaluusi_ajastin;
structitimervalold_timer;

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;

settimer (ITIMER_REAL, &new_timer, &old_timer);
signaali (SIGALRM, ajastin_takaisinsoitto);

sillä aikaa (nukkua (jäljellä) != 0)
{
jos (errno == EINTR)
debugf("Signaali keskeyttää lepotilan");
muu
errorf("univirhe %s", strerror (errno));
}

palata0;
}

Yllä oleva koodi käyttää nukkua() toiminto odottaa kolme sekuntia. Tänä aikana intervalliajastin toimii ensin yhden sekunnin ajan, sitten 300 millisekunnin välein.

Tallenna ja käännä mallikoodi nimen kanssa ymmärtääksesi paremmin intervalli.c:

$ gcc -o intervalli.c
$ aika ./väli
Signaali 14 kiinni numerosta 1653493614.325
debug: signaali keskeyttää nukkumisen (pääväli.c: 36)
Signaali 14 kiinni numerosta 1653493614.625
debug: signaali keskeyttää nukkumisen (pääväli.c: 36)
Signaali 14 kiinni numerosta 1653493614.925
debug: signaali keskeyttää nukkumisen (pääväli.c: 36)
Signaali 14 kiinni numerosta 1653493615.225
debug: signaali keskeyttää nukkumisen (pääväli.c: 36)
Signaali 14 kiinni numerosta 1653493615.525
...

Kuten voit nähdä lähdöstä ajastimen käynnin jälkeen, se kutsuu takaisinsoittotoimintoa 300 millisekunnin välein.

Hetken odottamisen jälkeen huomaat kuitenkin, että sovellus ei lopeta. Se jatkaa takaisinsoittotoiminnon suorittamista 300 millisekunnin välein. Jos suurennat intervalliarvoa millisekunteina, näet, että sovellus päättyy. Tämä johtuu laitteen käyttöalueesta nukkua() toiminto.

Ajastimien käytön tärkeys Linuxissa

Erityisesti reaaliaikaisissa sovelluksissa ajastinmekanismi on erittäin tärkeä. Tämä on myös ratkaisu, jota käytetään suorituskyvyn optimointiin. Voit jopa käyttää sitä mittaamaan käyttöaikaa tai latenssia sovelluksessasi. On tärkeää käyttää ajastinmekanismeja kuluneen ajan ja ajan siirtymätapahtumien seuraamiseen.

Ohjelmiston kääntäminen ja asentaminen lähteestä Linuxissa

Lue Seuraava

JaaTweetJaaSähköposti

Liittyvät aiheet

  • Ohjelmointi
  • Ohjelmointi
  • Linux Vinkkejä

Kirjailijasta

Fatih Küçükkarakurt (10 artikkelia julkaistu)

Insinööri ja ohjelmistokehittäjä, joka on matematiikan ja tekniikan fani. Hän on aina pitänyt tietokoneista, matematiikasta ja fysiikasta. Hän on kehittänyt pelimoottoriprojekteja sekä koneoppimista, keinotekoisia hermoverkkoja ja lineaarisia algebrakirjastoja. Lisäksi työskentelee edelleen koneoppimisen ja lineaaristen matriisien parissa.

Lisää Fatih Küçükkarakurtilta

tilaa uutiskirjeemme

Liity uutiskirjeemme saadaksesi teknisiä vinkkejä, arvosteluja, ilmaisia ​​e-kirjoja ja eksklusiivisia tarjouksia!

Klikkaa tästä tilataksesi