Tyhjäkäyntijakso

Idle loop (myös "idle waiting", englanniksi busy waiting) - odottamisen toteutus tietokoneohjelmassa, jossa tietty ehto tarkistetaan loputtomassa silmukassa. Poistuminen äärettömästä silmukasta tapahtuu vain, kun testattava ehto täyttyy.

Myös tyhjäkäyntisilmukkaa voidaan käyttää mielivaltaisen viiveen luomiseen ohjelman suorittamiseen.

Useimmissa tapauksissa tyhjäkäyntiä pidetään anti-mallina, jota tulisi välttää muokkaamalla koodi uudelleen tai käyttämällä erilaista kehitystapaa (asynkroninen suoritus, tapahtumaohjattu ohjelmointi jne.).

Esimerkkitoteutus C:ssä

Alla olevassa koodinpätkässä yksi säikeistä odottaa arvoa 0 muuttujassa i ja vasta sen jälkeen jatkaa suorittamista:

# sisältää <pthread.h> # sisältää <stdatomic.h> # sisältää <stdio.h> # sisältää <stdlib.h> # sisältää <unistd.h> /* i on globaali, joten se näkyy kaikille funktioille. Se hyödyntää erityistä * Kirjoita atomic_int, joka sallii atomimuistin käytön. */ atomi_int i = 0 ; /* f1 käyttää spinlockia odottaakseen, että i muuttuu 0:sta. */ staattinen void * f1 ( void * p ) { int paikallinen_i ; /* Lataa atomisesti i:n nykyinen arvo kohtaan local_i ja tarkista onko se arvo on nolla */ while (( paikallinen_i = atomikuorma ( & i )) == 0 ) { /* älä tee mitään - tarkista vain uudestaan ​​ja uudestaan ​​*/ } printf ( "i:n arvo on muuttunut %d:ksi. \n " , local_i ); return NULL ; } staattinen void * f2 ( void * p ) { int paikallinen_i = 99 ; nukkua ( 10 ); /* nuku 10 sekuntia */ atomic_store ( & i , paikallinen_i ); printf ( "t2 on muuttanut i:n arvon %d:ksi. \n " , local_i ); return NULL ; } int main () { int rc ; pthread_t t1 , t2 ; rc = pthread_create ( & t1 , NULL , f1 , NULL ); if ( rc != 0 ) { fprintf ( stderr , "pthread f1 epäonnistui \n " ); palauttaa EXIT_FAILURE ; } rc = pthread_create ( & t2 , NULL , f2 , NULL ); if ( rc != 0 ) { fprintf ( stderr , "pthread f2 epäonnistui \n " ); palauttaa EXIT_FAILURE ; } pthread_join ( t1 , NULL ); pthread_join ( t2 , NULL ); puts ( "Kaikki psäikeet valmis." ); paluu 0 ; }

Java-toteutusesimerkkejä

Tämä toteutus käyttää Thread.sleep()-menetelmän kutsua silmukassa, jonka avulla voit keskeyttää säikeen suorittamisen tietyn määrän millisekunteja:

pitkä viive = 1L ; // aika millisekunteina volatile boolean waitForEvent = true ; // arvo asetetaan muista säikeistä while ( waitForEvent ) { lanka . nukkua ( viive ); }

Samalla ajastin antaa laskentaresursseja muille säikeille, minkä vuoksi säikeen "nukkuminen" ja "herätys" ovat kalliita toimintoja. Toinen tämän menetelmän haittapuoli on tarve käsitellä poikkeusta sekä kyvyttömyys keskeyttää lanka alle 1 millisekunnin ajaksi. Java 9:stä lähtien on otettu käyttöön Thread.onSpinWait()-menetelmä, jonka avulla voit toteuttaa lyhyen odotuksen keskeyttämättä säiettä:

volatile boolean waitForEvent = true ; // arvo asetetaan muista säikeistä while ( waitForEvent ) { lanka . onSpitWait (); }

Tämän lähestymistavan etuna on kyky keskeyttää odotus välittömästi ja jatkaa suoritusta.

Matalan tason sovellus

Yksi tyhjäkäynnin odottamisen alatyypeistä on spinlock.

Matalan tason ohjelmoinnissa tyhjäkäyntisilmukoita käytetään laajemmin. Käytännössä keskeytys ei ole aina toivottavaa joillekin laitteistolaitteille. Jos esimerkiksi on tarpeen kirjoittaa laitteeseen ohjaustietoja ja saada vastaus kirjoituksen tuloksista, kehittäjä voi kääntyä viivetoimintoon käyttöjärjestelmätasolla, mutta sen kutsu voi kestää kauemmin, joten aktiivinen odotus sykliä käytetään.

Katso myös