Mehanizmi časovnika vam omogočajo načrtovanje jedra OS, da obvesti aplikacijo, ko poteče vnaprej določen čas. Običajno jih boste uporabili tako, da navedete dva podatka. Najprej morate določiti, koliko časa naj traja časovnik, preden obvesti. Drugič, pripraviti boste morali funkcijo povratnega klica, ki bo delovala, ko se to obvestilo pojavi.

Tradicionalni pristop k časovnikom

Mehanizmi časovnika v sistemih, ki temeljijo na Linuxu in Unixu, so se razvili, da bi služili različnim potrebam. Različni pristopi vam lahko pomagajo rešiti različne vrste težav. Vendar pa boste pogosto videli prvo različico alarm () mehanizem še vedno v uporabi.

Funkcija alarma je najpreprostejši način uporabe časovnika; tukaj je njegov prototip:

nepodpisanintalarm(nepodpisanint sekunde);

S to metodo lahko določite samo čas v celih sekundah. Ko se čas izteče, operacijski sistem pošlje datoteko SIGALRM signal vaši aplikaciji. Če želite obdelati potek časovnika v vaši aplikaciji, morate definirati tudi funkcijo povratnega klica.

instagram viewer

Tukaj je primer funkcije za obravnavo signala:

#vključujejo
#vključujejo
#vključujejo
#vključujejo

ničnatimer_callback(int signum)
{
time_t zdaj = čas (NIČ);
printf("Signal %d ujet na %li", signum, zdaj);
}

intglavni()
{
signal (SIGALRM, timer_callback);
alarm (1);
spi (3);
vrnitev0;
}

Ta koda dvigne a SIGALRM signal po 1 drugič. Če želite zakasnitev časovnika povečati na pet sekund, pokličite alarm (5) namesto tega. Če želite ustaviti časovnik, posredujte vrednost 0: alarm (0).

Ko se čas izteče, se časovnik, ki ga uporabljate, ne bo občasno znova zagnal. Na primer, če želite odložiti še eno sekundo, morate znova zagnati mehanizem z drugim klicem na alarm ().

Kljub enostavni uporabi ima ta metoda nekaj pomanjkljivosti:

  • Samo en časovnik naenkrat.
  • Brez periodične podpore za časovnik.
  • Časovno obdobje lahko podate samo v večkratnikih celih sekund.
  • Ni načina, da bi vedeli, koliko časa ostane na časovniku.

Shranite zgornji vzorec kode kot alarm.c. Kdaj prevedeš in zaženeš ga bo program poklical timer_callback deluje po eni sekundi. Nato bo počakal preostali dve sekundi zaradi spati (3) vrstico, nato prekinite.

$ gcc -o alarm alarm.c
$ čas ./alarm
Signal 14 ujet na 1653490465
realnih 0m1.004s
uporabnik 0m0.000s
sys 0m0,003s

Razlog za uporabo ukaza time je, da lahko vidite čase. Toda če pogledate rezultat, skupni čas delovanja ni tri sekunde. To je posledica SIGALRM signal iz alarm (1) ko poteče prva sekunda, medtem ko je sistemski klic zaradi delovanja funkcije spanja (3). Ko ta signal prispe, prekine sistemski klic, začet za spanje (3).

Uporaba intervalnega časovnika

Mehanizem intervalnega časovnika je bil prvič na voljo v različici 4.2 BSD. Bilo je kasneje standardiziran s strani POSIX. Njegove glavne prednosti pred tradicionalnimi alarm () Metoda časovnika, ki temelji na:

  • Zagotavlja mikrosekundno ločljivost.
  • Omogoča podrobnejši nadzor merjenja časa v treh različnih načinih.
  • Možno ga je nastaviti enkrat in redno delati.
  • V vsakem trenutku je mogoče ugotoviti, kako dolgo je prisoten.

Prototipi funkcij, ki se uporabljajo za intervalne operacije časovnika, so naslednji:

#vključujejo

intsetitimer(int ki, konst struct itimerval *novaValue, struct itimerval *oldValue);
intgetitimer(int ki, struct itimerval *value);

structitimerval
{
structčasovni okviritInterval;// naslednja vrednost
structčasovni okviritValue;// trenutna vrednost
};

structčasovni okvir
{
dolga tv_sec;
dolga tv_usec;
};

Če želite nastaviti intervalni časovnik, boste morali uporabiti itimerval struct. Prenesti boste morali vrednost z uporabo te strukture kot drugega argumenta v nastavitev funkcijo.

Na primer, intervalni časovnik, ki bo vašo aplikacijo obvestil za 1 sekundo in nato vsakih 300 milisekund, je mogoče nastaviti na naslednji način:

structitimervalnov časovnik;
structitimervalStarodobnik;

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

Če je pred nastavitvijo novih vrednosti aktiven intervalni časovnik, se njegove vrednosti prenesejo na naslov spremenljivke itimerval tip, ki je podan tretjemu parametru funkcije.

Z mehanizmom intervalnega časovnika lahko nastavite tri različne vrste časovnikov. Določite vrsto časovnika v prvem parametru setitimer():

Vrsta časovnika Signal Pojasnilo
ITIMER_REAL SIGALRM Neodvisno od časa, ki ga je aplikacija porabila, izračunanega na skupni pretečeni čas.
ITIMER_VIRTUAL SIGVTALRM Izračunano v času, ko se aplikacija izvaja samo v uporabniškem načinu.
ITIMER_PROF SIGPROF Izračunano glede na vsoto časa, ki ga je aplikacija porabila v uporabniškem in sistemskem načinu.

Iz te tabele lahko vidite, da je ITIMER_REAL tip pošlje a SIGALRM signal, tako kot alarm () funkcijo.

Uporaba intervalnega časovnika in alarm () v isti aplikaciji bo zmedeno. Čeprav lahko še enkrat preverite preostali čas z gettimer(), jih ni smiselno uporabljati hkrati.

Tukaj je primer definiranja funkcije upravljalnika signalov z glava za odpravljanje napak:

#vključujejo
#vključujejo
#vključujejo
#vključujejo
#vključujejo
#vključujejo
#vključujejo
#vključujejo "./debug.h"

ničnatimer_callback(int signum)
{
structčasovni okvirzdaj;
gettimeofday(&zdaj, NIČ);
printf("Signal %d je ujet na %li.%03li ", signum, now.tv_sec, now.tv_usec / 1000);
}

intglavni()
{
nepodpisanint preostali = 3;

structitimervalnov_timer;
structitimervalStarodobnik;

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, &nov_timer, &stari_timer);
signal (SIGALRM, timer_callback);

medtem (spi (preostane) != 0)
{
če (napačno == EINTR)
debugf("spanje je prekinjeno zaradi signala");
drugo
errorf("napaka mirovanja %s", strerror (errno));
}

vrnitev0;
}

Zgornja koda uporablja spanje () funkcijo počakajte tri sekunde. V tem času teče intervalni časovnik, najprej za eno sekundo, nato v intervalu 300 milisekund.

Za boljše razumevanje shranite in prevedite vzorčno kodo z imenom interval.c:

$ gcc -o interval intervala.c
$ čas ./interval
Signal 14 ujet na 1653493614.325
odpravljanje napak: mirovanje prekine signal (glavni interval.c: 36)
Signal 14 ujet na 1653493614.625
odpravljanje napak: mirovanje prekine signal (glavni interval.c: 36)
Signal 14 ujet na 1653493614.925
odpravljanje napak: mirovanje prekine signal (glavni interval.c: 36)
Signal 14 ujet na 1653493615.225
odpravljanje napak: mirovanje prekine signal (glavni interval.c: 36)
Signal 14 ujet na 1653493615.525
...

Kot lahko vidite iz izhoda po zagonu časovnika, pokliče funkcijo povratnega klica vsakih 300 milisekund.

Vendar pa boste po nekaj daljšem čakanju opazili, da se aplikacija ne konča. Še naprej izvaja funkcijo povratnega klica vsakih 300 milisekund. Če povečate vrednost intervala v milisekundah, boste videli, da se aplikacija konča. To je zaradi območja uporabe spanje () funkcijo.

Pomen uporabe časovnikov v Linuxu

Posebej za aplikacije v realnem času je mehanizem časovnika zelo pomemben. To je tudi rešitev, ki se uporablja za optimizacijo delovanja. Uporabite ga lahko celo za merjenje časa delovanja ali zakasnitve v vaši aplikaciji. Za spremljanje pretečenega časa in časovnih prehodov je pomembno, da uporabite mehanizme časovnika.

Kako prevesti in namestiti programsko opremo iz vira v Linuxu

Preberite Naprej

DelitiTweetDelitiE-naslov

Povezane teme

  • Programiranje
  • Programiranje
  • Nasveti za Linux

O avtorju

Fatih Küçükkarakurt (Objavljenih 10 člankov)

Inženir in razvijalec programske opreme, ki je ljubitelj matematike in tehnologije. Od nekdaj je imel rad računalništvo, matematiko in fiziko. Razvil je projekte motorjev za igre, pa tudi strojno učenje, umetne nevronske mreže in knjižnice linearne algebre. Poleg tega še naprej dela na strojnem učenju in linearnih matrikah.

Več od Fatih Küçükkarakurt

Naročite se na naše novice

Pridružite se našemu glasilu za tehnične nasvete, ocene, brezplačne e-knjige in ekskluzivne ponudbe!

Kliknite tukaj, da se naročite