Tomgångscykel

Idle loop (även "idle waiting", engelska busy waiting) - implementeringen av väntan i ett datorprogram, där ett visst tillstånd kontrolleras i en ändlös loop. Utträdet från den oändliga slingan sker endast när villkoret som testas är uppfyllt.

En tomgångsslinga kan också användas för att skapa en godtycklig fördröjning i programexekveringen.

I de flesta fall anses tomgångsslingan vara ett antimönster som bör undvikas genom att omfaktorisera koden eller använda en annan utvecklingsmetod (asynkron exekvering, händelsedriven programmering, etc.).

Ett exempel på implementering i C

I kodavsnittet nedan väntar en av trådarna på värdet 0 i variabeln i och bara efter det fortsätter exekveringen:

# include <pthread.h> # include <stdatomic.h> # include <stdio.h> # include <stdlib.h> # include <unistd.h> /* i är global, så den är synlig för alla funktioner. Den använder sig av det speciella * typ atomic_int, vilket tillåter atomminnesåtkomst. */ atomic_int i = 0 ; /* f1 använder ett spinlock för att vänta på att i ändras från 0. */ statiskt tomrum * f1 ( tomrum * p ) { int local_i ; /* Atomiskt ladda nuvarande värde för i till local_i och kontrollera om det värdet är noll */ while (( local_i = atomic_load ( & i )) == 0 ) { /* gör ingenting - fortsätt bara att kolla om och om igen */ } printf ( "i:s värde har ändrats till %d. \n " , local_i ); returnera NULL ; } statiskt tomrum * f2 ( tomrum * p ) { int local_i = 99 ; sömn ( 10 ); /* sova i 10 sekunder */ atomic_store ( & i , local_i ); printf ( "t2 har ändrat värdet på i till %d. \n " , local_i ); returnera NULL ; } int main () { int rc ; pthread_t t1 , t2 ; rc = pthread_create ( & t1 , NULL , f1 , NULL ); if ( rc != 0 ) { fprintf ( stderr , "pthread f1 misslyckades \n " ); returnera EXIT_FAILURE ; } rc = pthread_create ( & t2 , NULL , f2 , NULL ); if ( rc != 0 ) { fprintf ( stderr , "pthread f2 misslyckades \n " ); returnera EXIT_FAILURE ; } pthread_join ( t1 , NULL ); pthread_join ( t2 , NULL ); sätter ( "Alla pthreads färdiga." ); returnera 0 ; }

Exempel på Java-implementering

Den här implementeringen använder ett anrop till metoden Thread.sleep() i en loop, vilket gör att du kan avbryta exekveringen av en tråd under ett givet antal millisekunder:

lång fördröjning = 1L ; // tid i millisekunder volatile boolean waitForEvent = sant ; //-värdet är satt från andra trådar while ( waitForEvent ) { tråd . sömn ( fördröjning ); }

Samtidigt ger schemaläggaren datorresurser till andra trådar, vilket är anledningen till att "sova" och "väcka upp" en tråd är dyra operationer. En annan nackdel med denna metod är behovet av att hantera undantaget, såväl som oförmågan att suspendera tråden i mindre än 1 millisekund. Sedan Java 9 har metoden Thread.onSpinWait() introducerats, som låter dig implementera en kort väntan utan att pausa tråden:

volatile boolean waitForEvent = sant ; //-värdet är satt från andra trådar while ( waitForEvent ) { tråd . onSpitWait (); }

Fördelen med detta tillvägagångssätt är möjligheten att omedelbart avbryta väntan och fortsätta körningen.

Lågnivåapplikation

En av undertyperna av ledig väntan är ett spinlock.

I lågnivåprogrammering används tomgångsslingor mer allmänt. I praktiken är ett avbrott inte alltid önskvärt för vissa hårdvaruenheter. Till exempel, om det är nödvändigt att skriva viss kontrollinformation till enheten och få ett svar om resultatet av skrivningen, kan utvecklaren vända sig till fördröjningsfunktionen på OS-nivå, men dess anrop kan ta längre tid, så en aktiv väntan cykel används.

Se även