Üresjárati ciklus

Idle loop (más néven "tétlen várakozás", angol busy waiting) - a várakozás megvalósítása egy számítógépes programban, amelyben egy bizonyos feltételt egy végtelen ciklusban ellenőriznek. A végtelen hurokból való kilépés csak akkor következik be, ha a vizsgált feltétel teljesül.

Ezenkívül egy üresjárati ciklus tetszőleges késleltetést hozhat létre a program végrehajtásában.

A legtöbb esetben az üresjárati ciklus anti-mintának számít, amelyet el kell kerülni a kód átalakítása vagy más fejlesztési megközelítés (aszinkron végrehajtás, eseményvezérelt programozás stb.) alkalmazásával.

Egy példa megvalósítás C-ben

Az alábbi kódrészletben az egyik szál az i változóban a 0 értékre vár, és csak ezután folytatja a végrehajtást:

# include <pthread.h> # include <stdatomic.h> # include <stdio.h> # include <stdlib.h> # include <unistd.h> /* i globális, tehát minden függvény számára látható. Kihasználja a speciális * írja be az atomic_int, amely lehetővé teszi az atomi memória elérését. */ atom_int i = 0 ; /* Az f1 egy spinlockot használ, hogy megvárja, amíg az i átvált 0-ról. */ statikus üres * f1 ( érvénytelen * p ) { int local_i ; /* Az i aktuális értékét atomosan töltse be a local_i-be, és ellenőrizze, hogy ez az érték-e nulla */ while (( local_i = atom_load ( & i )) == 0 ) { /* ne csinálj semmit - csak ellenőrizd újra és újra */ } printf ( "i értéke %d-re változott. \n " , local_i ); return NULL ; } statikus üres * f2 ( érvénytelen * p ) { int lokális_i = 99 ; alvás ( 10 ); /* aludj 10 másodpercet */ atom_store ( & i , helyi_i ); printf ( "t2 megváltoztatta az i értékét %d-re. \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 , "f1 pthread nem sikerült \n " ); return EXIT_FAILURE ; } rc = pthread_create ( & t2 , NULL , f2 , NULL ); if ( rc != 0 ) { fprintf ( stderr , "f2 pthread nem sikerült \n " ); return EXIT_FAILURE ; } pthread_join ( t1 , NULL ); pthread_join ( t2 , NULL ); puts ( "Minden pthread kész." ); return 0 ; }

Java megvalósítási példák

Ez a megvalósítás a Thread.sleep() metódus meghívását használja egy ciklusban, amely lehetővé teszi egy szál végrehajtásának felfüggesztését egy adott számú ezredmásodpercre:

hosszú késleltetés = 1L ; // idő ezredmásodpercben volatile logikai érték waitForEvent = true ; // értéke más szálakból van beállítva while ( waitForEvent ) { szál . alvás ( késleltetés ); }

Ugyanakkor az ütemező számítási erőforrásokat ad más szálaknak, ezért egy szál "altatása" és "felébresztése" költséges művelet. A módszer másik hátránya, hogy kezelni kell a kivételt, valamint az, hogy a szálat nem lehet 1 milliszekundumnál rövidebb ideig felfüggeszteni. A Java 9 óta bevezették a Thread.onSpinWait() metódust, amely lehetővé teszi a rövid várakozás megvalósítását a szál szüneteltetése nélkül:

volatile logikai érték waitForEvent = true ; // értéke más szálakból van beállítva while ( waitForEvent ) { szál . onSpitWait (); }

Ennek a megközelítésnek az az előnye, hogy azonnal megszakíthatja a várakozást és folytathatja a végrehajtást.

Alacsony szintű alkalmazás

A tétlen várakozás egyik altípusa a spinlock.

Az alacsony szintű programozásban az üresjárati hurkokat szélesebb körben használják. A gyakorlatban a megszakítás nem mindig kívánatos egyes hardvereszközök esetében. Például, ha valamilyen vezérlő információt kell írni az eszközre és választ kapni az írás eredményéről, akkor a fejlesztő az operációs rendszer szintjén fordulhat a késleltetés funkcióhoz, de ennek hívása tovább tarthat, így aktív várakozás ciklust használják.

Lásd még