Kisan kunto

Kilpailuehto , myös kilpailu  [ 1] ,  on suunnitteluvirhe monisäikeisessä järjestelmässä tai sovelluksessa, jossa järjestelmän tai sovelluksen toiminta riippuu koodin osien suoritusjärjestyksestä. Virhe sai nimensä samanlaisesta suunnitteluvirheestä elektroniikkapiireissä (katso signaalikilpa ).

Termi kilpailutilanne viittaa tekniseen ammattislangiin ja on seurausta englanninkielisen vastineen huolimattomasta kirjaimellisesta käännöksestä. Tiukemmassa akateemisessa ympäristössä on tapana käyttää termiä concurrency uncertainty .

Kilpailutilanne on "kelluva" virhe ( heisenbug ), joka ilmestyy satunnaisesti ja " katoaa" kun yrität paikallistaa sen.

Mahdolliset seuraukset

Jaetun muistin hallitsemattoman käytön vuoksi kilpailutilanne voi johtaa täysin erilaisiin virheisiin, joita voi tapahtua arvaamattomina aikoina, ja yritys toistaa virhe virheenkorjaustarkoituksiin samanlaisilla käyttöolosuhteilla saattaa epäonnistua.

Tärkeimmät seuraukset voivat olla:

Therac-25 kotelo

Therac -25 sädehoitolaite oli ensimmäinen lääkinnällinen laite Yhdysvalloissa, joka turvasi yksinomaan ohjelmiston . Tämä laite toimi kolmessa tilassa:

  1. Elektronihoito : Elektronipistooli säteilyttää potilasta suoraan; tietokone asettaa elektronien energian 5 - 25 MeV .
  2. Röntgenhoito : Elektroniase säteilyttää volframikohdetta ja potilasta säteilytetään röntgensäteillä, jotka kulkevat kartiomaisen diffuusorin läpi. Tässä tilassa elektronin energia on vakio: 25 MeV .
  3. Kolmannessa tilassa ei ollut säteilyä. Teräsheijastin asetetaan elektronien tielle (onnettomuuden sattuessa), ja säteilyä simuloidaan valolla . Tätä tilaa käytetään suuntaamaan säde tarkasti kipeään kohtaan.

Nämä kolme tilaa asetettiin pyörivällä levyllä, jossa oli reikä, jossa oli poikkeutusmagneetit elektronista hoitoa varten, ja kohde, jossa oli diffuusori röntgensäteitä varten. Ohjausohjelman ja näppäimistömoottorin välisen kilpailutilanteen vuoksi joskus tapahtui, että röntgenhoitotilassa levy oli "Elektroniterapia"-asennossa ja potilasta säteilytettiin suoraan 25 MeV elektronisuihkulla, joka johti ylivalottumiseen. Samanaikaisesti anturit näyttivät "Zero dose", joten käyttäjä saattoi toistaa toimenpiteen, mikä pahentaa tilannetta. Seurauksena ainakin kaksi potilasta kuoli.

Osa koodista on otettu Therac-6:sta ja Therac-20:sta. Samaan aikaan Therac-6:ssa ei ollut röntgenhoitoa, ja Therac-20:ssä oli laitteistoturvatoimenpiteitä, jotka estivät säteilyä syttymästä, kun levy oli väärässä asennossa.

Esimerkki

Harkitse koodiesimerkkiä ( Javalla ).

haihtuva int x ; // Säie 1: while ( ! stop ) { x ++ ; } // Säie 2: while ( ! stop ) { if ( x % 2 == 0 ) System . ulos . println ( "x=" + x ); }

Olkoon x=0. Oletetaan, että ohjelma suoritetaan seuraavassa järjestyksessä:

  1. Säikeen 2 if-lause testaa x :n pariteetin.
  2. Säikeen 1 lauseke " x++ " kasvaa x yhdellä.
  3. Säikeen 2 lähtökäsky tulostaa " x=1 ", vaikka muuttuja näyttää olevan pariteettitarkistettu.

Ratkaisut

Paikallinen kopio

Helpoin tapa ratkaista tämä on kopioida muuttuja x paikalliseen muuttujaan. Tässä on korjattu koodi:

// Säie 2: while ( ! stop ) { int välimuistissa_x = x ; if ( välimuistissa_x % 2 == 0 ) Järjestelmä . ulos . println ( "x=" + välimuistissa_x ); }

Tämä menetelmä toimii luonnollisesti vain, kun muuttujia on vain yksi ja kopiointi tapahtuu yhdessä konekäskyssä.

Synkronointi

Monimutkaisempi ja "kallimpi", mutta myös yleisempi ratkaisumenetelmä on säietynkronointi , nimittäin:

int x ; // Säie 1: while ( ! stop ) { synkronoitu ( someObject ) { x ++ ; } } // Säie 2: while ( ! stop ) { synchronized ( someObject ) { if ( x % 2 == 0 ) System . ulos . println ( "x=" + x ); } }

Tässä tapahtuu ennen kuin semantiikka ei vaadi avainsanaa volatile.

Yhdistetty tapa

Oletetaan, että muuttujia on kaksi (ja avainsanalla volatileei ole vaikutusta), ja toisella säikeellä System.out.printlnon sen sijaan monimutkaisempi käsittely. Tässä tapauksessa molemmat menetelmät ovat epätyydyttäviä: ensimmäinen, koska yksi muuttuja voi muuttua, kun toista kopioidaan; toinen johtuu siitä, että liian paljon koodia synkronoidaan.

Näitä menetelmiä voidaan yhdistää kopioimalla "vaarallisia" muuttujia synkronoituun lohkoon. Toisaalta tämä poistaa yhden konekäskyn rajoituksen, toisaalta sen avulla pääset eroon liian suurista synkronointilohkoista.

haihtuva int x1 , x2 ; // Säie 1: while ( ! stop ) { synkronoitu ( someObject ) { x1 ++ ; x2 ++ ; } } // Säie 2: while ( ! stop ) { int välimuistissa_x1 , välimuistissa_x2 ; synkronoitu ( jokuObjekti ) { välimuistissa_x1 = x1 ; välimuistissa_x2 = x2 ; } if (( välimuistiin_x1 + välimuistiin_x2 ) % 100 == 0 ) DoSomethingComplicated ( välimuisti_x1 , välimuisti_x2 ); }

Ei ole ilmeisiä tapoja havaita ja korjata kilpailuolosuhteet. Paras tapa päästä eroon kilpailuista on suunnitella oikein moniajojärjestelmä.

Hakkerointia kilpailuolosuhteita hyödyntämällä

On olemassa virheluokka (ja niitä hyödyntävät hyökkäystyypit), jotka sallivat  etuoikeutettujen ohjelmien vaikuttaa muiden ohjelmien toimintaan muuttamalla julkisia resursseja (yleensä väliaikaisia ​​tiedostoja  ; tiedosto on kaikkien tai osan kirjoitettavissa). järjestelmän käyttäjiä ohjelmoijan virheen vuoksi.

Hyökkäävä ohjelma voi tuhota tiedoston sisällön, jolloin uhriohjelma kaatuu, tai tietoja muuttamalla pakottaa ohjelman suorittamaan jonkin toiminnon sen oikeuksien tasolla.

Tästä syystä ohjelmistot, joilla on vakavia tietoturvavaatimuksia, kuten verkkoselain , käyttävät salauslaatuisia satunnaislukuja väliaikaisten tiedostojen nimeämiseen.

Muistiinpanot

  1. Raymond, Eric S. Unix-ohjelmoinnin taito / käänn. englannista. - M . : Kustantaja " Williams ", 2005. - S. 202. - 544 s. — ISBN 5-8459-0791-8 .
  2. ↑ 1 2 3 4 Greg Kroah-Hartman, Alessandro Rubini, Jonathan Corbet. Luku 5. Samanaikaisuus ja kilpailuehdot // Linux-laiteohjaimet . - 3. painos. - O'Reilly Media, Inc., 2005. - ISBN 0596005903 . Arkistoitu 12. huhtikuuta 2019 Wayback Machinessa

Katso myös