Bralci, kot ste vi, pomagajo podpirati MUO. Ko opravite nakup prek povezav na našem spletnem mestu, lahko zaslužimo partnersko provizijo.
Pogoj dirke se pojavi, ko se morata dve operaciji izvesti v določenem vrstnem redu, vendar se lahko izvajata v nasprotnem vrstnem redu.
Na primer, v večnitni aplikaciji lahko dve ločeni niti dostopata do skupne spremenljivke. Posledično, če ena nit spremeni vrednost spremenljivke, lahko druga še vedno uporablja starejšo različico in ignorira najnovejšo vrednost. To bo povzročilo neželene rezultate.
Za boljše razumevanje tega modela bi bilo dobro natančno preučiti proces preklopa procesorja.
Kako procesor preklaplja med procesi
Sodobni operacijski sistemi lahko izvaja več kot en proces hkrati, kar se imenuje večopravilnost. Ko na ta proces pogledate z vidika Izvršilni cikel procesorja, boste morda ugotovili, da večopravilnost v resnici ne obstaja.
Namesto tega procesorji nenehno preklapljajo med procesi, da jih izvajajo hkrati ali se vsaj obnašajo, kot da to počnejo. CPE lahko prekine proces, preden se ta zaključi, in nadaljuje z drugim procesom. Operacijski sistem nadzira upravljanje teh procesov.
Na primer, algoritem Round Robin, eden najpreprostejših preklopnih algoritmov, deluje na naslednji način:
Na splošno ta algoritem omogoča, da se vsak proces izvaja zelo majhne dele časa, kot določi operacijski sistem. To je lahko na primer obdobje dveh mikrosekund.
CPE prevzame vsak proces po vrsti in izvede ukaze, ki se izvajajo dve mikrosekundi. Nato nadaljuje z naslednjim procesom, ne glede na to, ali se je trenutni končal ali ne. Tako se z vidika končnega uporabnika zdi, da se več kot en proces izvaja hkrati. Vendar, ko pogledate v zakulisje, CPE še vedno dela stvari v redu.
Mimogrede, kot kaže zgornji diagram, algoritem Round Robin nima pojmov o prednostni optimizaciji ali obdelavi. Posledično je to precej rudimentarna metoda, ki se redko uporablja v resničnih sistemih.
Zdaj, da bi vse to bolje razumeli, si predstavljajte, da tečeta dve niti. Če niti dostopajo do skupne spremenljivke, lahko pride do dirkanja.
Primer spletne aplikacije in tekmovalnih pogojev
Oglejte si preprosto aplikacijo Flask spodaj, da razmislite o konkretnem primeru vsega, kar ste do zdaj prebrali. Namen te aplikacije je upravljanje denarnih transakcij, ki bodo potekale na spletu. Shranite naslednje v datoteko z imenom money.py:
od bučko uvoz Bučka
od flask.ext.sqlalchemy uvoz SQLAlchemyapp = Flask (__ime__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy (aplikacija)razredračun(db. model):
id = db. Stolpec (db. Celo število, primarni_ključ = Prav)
količina = db. Stolpec (db. Vrvica(80), edinstven = Prav)def__v__(sam, štetje):
self.amount = znesekdef__repr__(sebe):
vrnitev '' % samo.znesek@app.route("/")
defživjo():
račun = Account.query.get(1) # Obstaja samo ena denarnica.
vrnitev "Skupni denar = {}".format (račun.znesek)@app.route("/pošlji/")
defposlati(znesek):
račun = Account.query.get(1)če int (račun.znesek) < znesek:
vrnitev "Nezadostno ravnotežje. Ponastavi denar z /reset!)"account.amount = int (account.amount) - znesek
db.session.commit()
vrnitev "Poslani znesek = {}".format (znesek)@app.route("/reset")
defponastaviti():
račun = Account.query.get(1)
račun.znesek = 5000
db.session.commit()
vrnitev "Ponastavitev denarja."
če __ime__ == "__glavno__":
app.secret_key = 'heLLoTHisIsSeCReTKey!'
app.run()
Če želite zagnati to kodo, boste morali ustvariti zapis v tabeli računa in nadaljevati transakcije nad tem zapisom. Kot lahko vidite v kodi, je to testno okolje, zato izvaja transakcije glede na prvi zapis v tabeli.
od denar uvoz db
db.create_all()
od denar uvoz račun
račun = račun (5000)
db.seja.dodaj(račun)
db.seja.zavezati()
Zdaj ste ustvarili račun s stanjem v višini 5000 $. Na koncu zaženite zgornjo izvorno kodo z naslednjim ukazom, če imate nameščena paketa Flask in Flask-SQLAlchemy:
pythondenar.py
Torej imate spletno aplikacijo Flask, ki izvede preprost postopek ekstrakcije. Ta aplikacija lahko izvaja naslednje operacije s povezavami do zahtev GET. Ker Flask privzeto deluje na vratih 5000, je naslov, na katerem dostopate do njega 127.0.0.1:5000/. Aplikacija ponuja naslednje končne točke:
- 127.0.0.1:5000/ prikazuje trenutno stanje.
- 127.0.0.1:5000/pošlji/{znesek} odšteje znesek z računa.
- 127.0.0.1:5000/ponastavitev ponastavi račun na 5000 $.
Zdaj, na tej stopnji, lahko preverite, kako se pojavi ranljivost pogojev tekmovanja.
Verjetnost ranljivosti dirkalnih pogojev
Zgornja spletna aplikacija vsebuje možno ranljivost pogojev tekmovanja.
Predstavljajte si, da imate za začetek 5000 USD in ustvarite dve različni zahtevi HTTP, ki bosta poslali 1 USD. Za to lahko na povezavo pošljete dve različni zahtevi HTTP 127.0.0.1:5000/pošlji/1. Predpostavi, da takoj, ko spletni strežnik obdela prvo zahtevo, CPE ta proces ustavi in obdela drugo zahtevo. Na primer, prvi proces se lahko ustavi po zagonu naslednje vrstice kode:
račun.znesek = int(account.amount) - znesek
Ta koda je izračunala novo skupno vrednost, vendar še ni shranila zapisa v bazo podatkov. Ko se začne druga zahteva, bo izvedel enak izračun, pri čemer bo odštel 1 USD od vrednosti v zbirki podatkov – 5000 USD – in shranil rezultat. Ko se prvi postopek nadaljuje, bo shranil lastno vrednost – 4999 USD – ki ne bo odražala zadnjega stanja na računu.
Torej, dve zahtevi sta bili zaključeni in vsaka bi morala odšteti 1 $ od stanja na računu, kar je povzročilo novo stanje v višini 4.998 $. Toda glede na vrstni red, v katerem jih spletni strežnik obdeluje, lahko končno stanje na računu znaša 4999 USD.
Predstavljajte si, da v ciljni sistem pošljete 128 zahtev za nakazilo v višini 1 USD v časovnem okviru petih sekund. Kot rezultat te transakcije bo pričakovani izpisek na računu znašal 5.000 $ - 128 $ = 4.875 $. Vendar se lahko zaradi pogojev dirke končno stanje razlikuje med 4.875 $ in 4.999 $.
Programerji so ena najpomembnejših komponent varnosti
Pri programskem projektu imate kot programer kar nekaj obveznosti. Zgornji primer je bil za preprosto aplikacijo za prenos denarja. Predstavljajte si, da delate na projektu programske opreme, ki upravlja bančni račun ali zaledje velikega spletnega mesta za e-trgovino.
S takšnimi ranljivostmi morate biti seznanjeni, da program, ki ste ga napisali za njihovo zaščito, ne vsebuje ranljivosti. To zahteva močno odgovornost.
Ranljivost dirkalnih pogojev je le ena izmed njih. Ne glede na to, katero tehnologijo uporabljate, morate biti pozorni na ranljivosti v kodi, ki jo pišete. Ena najpomembnejših veščin, ki jih lahko pridobite kot programer, je poznavanje varnosti programske opreme.