Mehanizmi mjerača vremena omogućuju vam da rasporedite jezgru OS-a da obavijesti aplikaciju kada protekne unaprijed određeno vrijeme. Obično ćete ih koristiti pružanjem dvije informacije. Prvo, morat ćete odrediti koliko vremena treba odbrojavati prije obavijesti. Drugo, morat ćete pripremiti funkciju povratnog poziva koja će djelovati kada dođe do te obavijesti.
Tradicionalni pristup mjeračima vremena
Mehanizmi mjerača vremena u sustavima temeljenim na Linuxu i Unixu evoluirali su kako bi zadovoljili različite potrebe. Različiti pristupi mogu vam pomoći u rješavanju različitih vrsta problema. Međutim, često ćete vidjeti prvu verziju alarm() mehanizam još uvijek u upotrebi.
Funkcija alarma najjednostavniji je način korištenja timera; evo njegovog prototipa:
nepotpisanintalarm(nepotpisanint sekunde);
Koristeći ovu metodu, možete odrediti samo vrijeme u cijelim sekundama. Kada vrijeme istekne, operativni sustav šalje SIGALRM signal za vašu aplikaciju. Za obradu isteka timera u svojoj aplikaciji, također biste trebali definirati funkciju povratnog poziva.
Evo primjera funkcije rukovanja signalom:
#uključiti
#uključiti
#uključiti
#uključitiponištititimer_callback(int signum)
{
time_t sada = vrijeme(NULL);
printf("Signal %d uhvaćen na %li", signum, sada);
}
intglavni()
{
signal (SIGALRM, timer_callback);
alarm(1);
spavati(3);
povratak0;
}
Ovaj kod podiže a SIGALRM signal nakon 1 drugi. Ako želite povećati odgodu timera na pet sekundi, samo nazovite alarm (5) umjesto toga. Da biste zaustavili mjerač vremena, proslijedite vrijednost 0: alarm (0).
Kada vrijeme istekne, mjerač vremena koji koristite neće se povremeno ponovno pokretati. Na primjer, ako želite odgoditi još jednu sekundu, trebali biste ponovno pokrenuti mehanizam s drugim pozivom na alarm().
Unatoč jednostavnosti korištenja, ova metoda ima neke nedostatke:
- Samo jedan po jedan mjerač vremena.
- Nema podrške za povremeni mjerač vremena.
- Vremensko razdoblje možete dati samo u višestrukim cijelim sekundama.
- Nema načina da se zna koliko je vremena ostalo na timeru.
Spremite gornji primjer koda kao alarm.c. Kada sastavljate i izvodite to, program će pozvati timer_callback funkcionirati nakon jedne sekunde. Zatim će pričekati preostale dvije sekunde zbog spavati (3) liniju, a zatim prekinuti.
$ gcc -o alarm alarma.c
$ vrijeme ./alarm
Signal 14 uhvaćen na 1653490465
stvarnih 0m1.004s
korisnik 0m0.000s
sys 0m0.003s
Razlog za korištenje naredbe time je mogućnost vidjeti vremena. Ali ako pogledate rezultat, ukupno vrijeme rada nije tri sekunde. To je zbog SIGALRM signal iz alarm (1) kada istekne prva sekunda, dok je sistemski poziv uzrokovano pokretanjem funkcije spavanja (3). Kada ovaj signal stigne, prekida sistemski poziv pokrenut za spavati (3).
Korištenje intervalnog mjerača vremena
Mehanizam intervalnog tajmera prvi je put bio dostupan u verziji 4.2 BSD. Bilo je to kasnije standardiziran od strane POSIX-a. Njegove glavne prednosti u odnosu na tradicionalne alarm() Metode mjerača vremena su:
- Omogućuje mikrosekundnu rezoluciju.
- Omogućuje detaljniju kontrolu mjerenja vremena u tri različita načina rada.
- Moguće ga je postaviti jednom i povremeno raditi.
- U svakom trenutku moguće je saznati koliko je dugo prisutan.
Prototipovi funkcija koji se koriste za intervalne operacije su sljedeći:
#uključiti
intsetitimer(int koji, konst struct itimerval *newValue, struct itimerval *oldValue);
intgetitimer(int koji, struct itimerval *vrijednost);strukturiratiitimerval
{
strukturirativremenski razmakitInterval;// sljedeća vrijednost
strukturirativremenski razmakitValue;// Trenutna vrijednost
};
strukturirativremenski razmak
{
dugo tv_sec;
dugo tv_usec;
};
Ako želite postaviti intervalni mjerač vremena, morat ćete koristiti itimerval strukturirati. Morat ćete proslijediti vrijednost koristeći ovu strukturu kao drugi argument u mjerač vremena za podešavanje funkcija.
Na primjer, intervalni mjerač vremena koji će obavijestiti vašu aplikaciju na 1 sekundu, a zatim svakih 300 milisekundi može se postaviti na sljedeći način:
strukturiratiitimervalnoviTimer;
strukturiratiitimervaloldTimer;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);
Ako je aktivan intervalni mjerač vremena prije postavljanja novih vrijednosti, njegove vrijednosti se prenose na adresu varijable itimerval tip koji se daje trećem parametru funkcije.
Možete postaviti tri različite vrste mjerača vremena s mehanizmom intervalnog mjerača vremena. Odredite vrstu tajmera u prvom parametru setitimer():
Vrsta mjerača vremena | Signal | Obrazloženje |
---|---|---|
ITIMER_REAL | SIGALRM | Neovisno o vremenu koje je aplikacija potrošila, računato na ukupno proteklo vrijeme. |
ITIMER_VIRTUAL | SIGVTALRM | Izračunato kroz vrijeme dok aplikacija radi samo u korisničkom načinu. |
ITIMER_PROF | SIGPROF | Izračunava se preko zbroja vremena koje je aplikacija provela u korisničkom i sustavnom načinu rada. |
Iz ove tablice možete vidjeti da je ITIMER_REAL tip šalje a SIGALRM signal, baš kao alarm() funkcija.
Korištenje intervalnog mjerača vremena i alarm() u istoj aplikaciji bit će zbunjujuće. Iako možete još jednom provjeriti preostalo vrijeme s gettimer(), nema smisla koristiti ih istovremeno.
Ovdje je primjer definiranja funkcije rukovanja signalom s zaglavlje za otklanjanje pogrešaka:
#uključiti
#uključiti
#uključiti
#uključiti
#uključiti
#uključiti
#uključiti
#uključiti "./debug.h"poništititimer_callback(int signum)
{
strukturirativremenski razmaksada;
gettimeofday(&sada, NULL);
printf("Signal %d uhvaćen na %li.%03lja ", signum, now.tv_sec, now.tv_usec / 1000);
}intglavni()
{
nepotpisanint preostali = 3;strukturiratiitimervalnovi_timer;
strukturiratiitimervalold_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;setitimer (ITIMER_REAL, &new_timer, &old_timer);
signal (SIGALRM, timer_callback);dok (spavati (preostalo) != 0)
{
ako (errno == EINTR)
debugf("Spavanje prekinuto signalom");
drugo
errorf("greška spavanja %s", strerror (errno));
}
povratak0;
}
Gornji kod koristi spavati() funkciju čekanja tri sekunde. Za to vrijeme radi intervalni mjerač vremena, prvo na jednu sekundu, a zatim na interval od 300 milisekundi.
Za bolje razumijevanje, spremite i kompajlirajte uzorak koda s imenom interval.c:
$ gcc -o interval intervala.c
$ vrijeme ./interval
Signal 14 uhvaćen na 1653493614.325
debug: mirovanje prekinuto signalom (glavni interval.c: 36)
Signal 14 uhvaćen na 1653493614.625
debug: mirovanje prekinuto signalom (glavni interval.c: 36)
Signal 14 uhvaćen na 1653493614.925
debug: mirovanje prekinuto signalom (glavni interval.c: 36)
Signal 14 uhvaćen na 1653493615.225
debug: mirovanje prekinuto signalom (glavni interval.c: 36)
Signal 14 uhvaćen na 1653493615.525
...
Kao što možete vidjeti iz izlaza nakon što se timer pokrene, on poziva funkciju povratnog poziva svakih 300 milisekundi.
Međutim, nakon malo dužeg čekanja, primijetit ćete da se aplikacija ne prekida. I dalje pokreće funkciju povratnog poziva svakih 300 milisekundi. Ako povećate vrijednost intervala u milisekundama, vidjet ćete da se aplikacija završava. To je zbog područja upotrebe spavati() funkcija.
Važnost korištenja mjerača vremena u Linuxu
Posebno za aplikacije u stvarnom vremenu, mehanizam timera je od velike važnosti. Ovo je također rješenje koje se koristi za optimizaciju performansi. Možete ga čak koristiti za mjerenje vremena neprekidnog rada ili kašnjenja u svojoj aplikaciji. Važno je koristiti mehanizme timera za praćenje proteklog vremena i događaja vremenskog prijelaza.
Kako kompajlirati i instalirati softver iz izvora u Linuxu
Pročitajte dalje
Povezane teme
- Programiranje
- Programiranje
- Savjeti za Linux
O autoru
Inženjer i programer koji je ljubitelj matematike i tehnologije. Oduvijek je volio računala, matematiku i fiziku. Razvio je projekte motora za igre, kao i strojno učenje, umjetne neuronske mreže i biblioteke linearne algebre. Štoviše, nastavlja raditi na strojnom učenju i linearnim matricama.
Pretplatite se na naše obavijesti
Pridružite se našem biltenu za tehničke savjete, recenzije, besplatne e-knjige i ekskluzivne ponude!
Kliknite ovdje za pretplatu