En race condition , også en konkurrence [ 1 ] , er en designfejl i et flertrådet system eller applikation, hvor driften af systemet eller applikationen afhænger af den rækkefølge, som dele af koden udføres i. Fejlen har fået sit navn fra en lignende designfejl i elektroniske kredsløb (se signal racing ).
Udtrykket race condition refererer til teknisk jargon og er resultatet af en sjusket bogstavelig oversættelse af den engelske ækvivalent. I et mere stringent akademisk miljø er det sædvanligt at bruge udtrykket concurrency uncertainty .
En race condition er en "flydende" fejl ( heisenbug ), som dukker op på tilfældige tidspunkter og "forsvinder", når du forsøger at lokalisere den.
På grund af ukontrolleret adgang til delt hukommelse kan en race-tilstand føre til helt andre fejl, der kan opstå på uforudsigelige tidspunkter, og et forsøg på at replikere fejlen til fejlfindingsformål med lignende driftsbetingelser kan mislykkes.
De vigtigste konsekvenser kan være:
Therac -25 strålebehandlingsmaskinen var den første medicinske enhed i USA, der udelukkende var afhængig af software for sikkerhed . Denne enhed fungerede i tre tilstande:
Disse tre tilstande blev indstillet af en roterende skive, hvori der var et hul med afbøjningsmagneter til elektronisk terapi, og et mål med en diffuser til røntgen. På grund af en kapløbstilstand mellem kontrolprogrammet og tastaturmotoren skete det nogle gange, at disken i røntgenterapitilstanden var i positionen "Elektronterapi", og patienten blev direkte bestrålet med en 25 MeV elektronstråle, som førte til overeksponering. Samtidig viste sensorerne "Nul dosis", så operatøren kunne gentage proceduren, hvilket forværrede situationen. Som følge heraf døde mindst to patienter.
En del af koden blev hentet fra Therac-6 og Therac-20. Samtidig havde Therac-6 ikke røntgenbehandling, og Therac-20 havde hardwaresikkerhedsforanstaltninger, der forhindrede strålingen i at tænde, når disken var i den forkerte position.
Overvej et kodeeksempel (i Java ).
flygtig int x ; // Tråd 1: while ( ! stop ) { x ++ ; … } // Tråd 2: while ( ! stop ) { if ( x % 2 == 0 ) System . ud . println ( "x=" + x ); … }Lad x=0. Antag, at programmet udføres i følgende rækkefølge:
Den nemmeste måde at løse dette på er at kopiere variablen x til en lokal variabel. Her er den rettede kode:
// Tråd 2: while ( ! stop ) { int cached_x = x ; if ( cachelagret_x % 2 == 0 ) System . ud . println ( "x=" + cachelagret_x ); … }Naturligvis fungerer denne metode kun, når der kun er én variabel, og kopiering udføres i én maskininstruktion.
En mere kompleks og "dyr", men også mere universel løsningsmetode er trådsynkronisering , nemlig:
int x ; // Tråd 1: while ( ! stop ) { synchronized ( someObject ) { x ++ ; } … } // Tråd 2: while ( ! stop ) { synchronized ( someObject ) { if ( x % 2 == 0 ) System . ud . println ( "x=" + x ); } … }Her sker det før semantik ikke kræver nøgleordet volatile.
Antag, at der er to variable (og nøgleordet volatilehar ingen effekt), og den anden tråd System.out.printlnhar mere kompleks behandling i stedet. I dette tilfælde er begge metoder utilfredsstillende: den første, fordi den ene variabel kan ændre sig, mens den anden kopieres; det andet skyldes, at for meget kode er synkroniseret.
Disse metoder kan kombineres ved at kopiere "farlige" variabler i en synkroniseret blok. På den ene side vil dette fjerne begrænsningen på én maskininstruktion, på den anden side vil det give dig mulighed for at slippe af med for store synkroniseringsblokke.
flygtig int x1 , x2 ; // Tråd 1: while ( ! stop ) { synchronized ( someObject ) { x1 ++ ; x2 ++ ; } … } // Tråd 2: while ( ! stop ) { int cached_x1 , cached_x2 ; synchronized ( someObject ) { cached_x1 = x1 ; cachelagret_x2 = x2 ; } if (( cached_x1 + cached_x2 ) % 100 == 0 ) DoSomethingComplicated ( cached_x1 , cached_x2 ); … }Der er ingen åbenlyse måder at opdage og rette løbsforhold på. Den bedste måde at slippe af med racer er at designe et multitasking-system korrekt.
Der er en klasse af fejl (og typer af angreb, der udnytter dem), der tillader et uprivilegeret program at påvirke driften af andre programmer gennem evnen til at ændre offentlige ressourcer (normalt midlertidige filer ; filen er tilgængelig til skrivning af hele eller dele af brugere af systemet på grund af en programmørs fejl.
Det angribende program kan ødelægge indholdet af filen, få offerprogrammet til at gå ned, eller ved at ændre dataene tvinge programmet til at udføre en handling på niveau med dets privilegier.
Det er af denne grund, at software med alvorlige sikkerhedskrav, såsom webbrowseren , bruger tilfældige tal i kryptografisk kvalitet til at navngive midlertidige filer.