Teiesugused lugejad aitavad MUO-d toetada. Kui teete ostu meie saidil olevate linkide abil, võime teenida sidusettevõtte komisjonitasu.
Võistlusseisund tekib siis, kui kaks toimingut peavad toimuma kindlas järjekorras, kuid need võivad toimuda ka vastupidises järjekorras.
Näiteks mitme lõimega rakenduses võivad kaks eraldi lõime pääseda ühisele muutujale juurde. Selle tulemusel, kui üks lõim muudab muutuja väärtust, võib teine lõime siiski kasutada vanemat versiooni, ignoreerides uusimat väärtust. See põhjustab soovimatuid tulemusi.
Selle mudeli paremaks mõistmiseks oleks hea protsessori protsesside ümberlülitamise protsessi põhjalikult uurida.
Kuidas protsessor protsesse vahetab
Kaasaegsed operatsioonisüsteemid võib samaaegselt käivitada rohkem kui ühte protsessi, mida nimetatakse multitegumtöötluseks. Kui vaatate seda protsessi nii CPU täitmistsükkel, võite avastada, et multitegumtööd pole tegelikult olemas.
Selle asemel vahetavad protsessorid pidevalt protsesse, et neid samaaegselt käitada või vähemalt käituda nii, nagu nad seda teeksid. Protsessor võib protsessi katkestada enne selle lõppemist ja jätkata mõne muu protsessiga. Operatsioonisüsteem kontrollib nende protsesside juhtimist.
Näiteks Round Robini algoritm, üks lihtsamaid lülitusalgoritme, töötab järgmiselt:
Üldiselt võimaldab see algoritm igal protsessil töötada väga väikese aja jooksul, nagu operatsioonisüsteem määrab. Näiteks võib see olla kahe mikrosekundi pikkune periood.
CPU võtab iga protsessi kordamööda ja täidab käske, mis töötavad kaks mikrosekundit. Seejärel jätkatakse järgmise protsessiga, olenemata sellest, kas praegune on lõppenud või mitte. Seega näib lõppkasutaja seisukohalt korraga töötavat rohkem kui üks protsess. Kui aga vaadata telgitagustesse, siis CPU teeb asju ikka korralikult.
Muide, nagu ülaltoodud diagramm näitab, puudub Round Robini algoritmil optimeerimise või töötlemise prioriteedi mõiste. Seetõttu on see üsna algeline meetod, mida reaalsetes süsteemides kasutatakse harva.
Nüüd, et kõike seda paremini mõista, kujutage ette, et jookseb kaks lõime. Kui lõimed pääsevad juurde ühisele muutujale, võib tekkida võistlustingimus.
Veebirakenduse ja võistlustingimuste näide
Vaadake allolevat lihtsat Flask rakendust, et mõtiskleda konkreetse näite üle kõigest, mida olete seni lugenud. Selle rakenduse eesmärk on hallata veebis toimuvaid rahatehinguid. Salvestage järgnev faili nimega raha.py:
alates kolb importida Kolb
alates kolb.ext.sqlalchemy importida SQLAlkeemiarakendus = Kolb (__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy (rakendus)klassKonto(db. mudel):
id = db. Veerg (db. Täisarv, esmane_võti = Tõsi)
summa = db. Veerg (db. String(80), ainulaadne = Tõsi)def__selles__(ise, loe):
ise.summa = summadef__repr__(ise):
tagasi '' % omasumma@app.route("/")
defTere():
konto = Account.query.get(1) # Rahakott on ainult üks.
tagasi "Kogu raha = {}".formaat (account.amount)@app.route("/send/")
defsaada(summa):
konto = Account.query.get(1)kui int (konto.summa) < summa:
tagasi "Ebapiisav tasakaal. Lähtestage raha koos /reset!)"konto.summa = int (konto.summa) - summa
db.session.commit()
tagasi "Saadetud summa = {}".formaat (summa)@app.route("/reset")
deflähtestada():
konto = Account.query.get(1)
konto.summa = 5000
db.session.commit()
tagasi "Raha lähtestatakse."
kui __name__ == "__main__":
app.secret_key = 'heLLoTHisIsSeCReTKey!'
app.run()
Selle koodi käitamiseks peate kontotabelis looma kirje ja jätkama selle kirjega tehinguid. Nagu koodist näha, on tegemist testkeskkonnaga, seega teeb see tehinguid tabeli esimese kirje alusel.
alates raha importida db
db.create_all()
alates raha importida Konto
konto = konto (5000)
db.seanss.lisama(konto)
db.seanss.commit()
Olete nüüd loonud konto, mille saldo on 5000 dollarit. Lõpuks käivitage ülaltoodud lähtekood järgmise käsuga, eeldusel, et teil on installitud paketid Flask ja Flask-SQLAlchemy:
püütonraha.py
Seega on teil veebirakendus Flask, mis teeb lihtsa ekstraheerimisprotsessi. See rakendus saab GET-i päringu linkidega teha järgmisi toiminguid. Kuna Flask töötab vaikimisi pordis 5000, on sellele juurdepääsetav aadress 127.0.0.1:5000/. Rakendus pakub järgmisi lõpp-punkte:
- 127.0.0.1:5000/ kuvab hetkeseisu.
- 127.0.0.1:5000/send/{summa} lahutab summa kontolt.
- 127.0.0.1:5000/lähtestamine lähtestab konto 5000 dollarile.
Nüüd saate selles etapis uurida, kuidas rassitingimuste haavatavus ilmneb.
Rassitingimuste haavatavuse tõenäosus
Ülaltoodud veebirakendus sisaldab võimalikku võistlustingimuste haavatavust.
Kujutage ette, et teil on alustuseks 5000 dollarit ja looge kaks erinevat HTTP-päringut, mis saadavad 1 dollari. Selleks saate lingile saata kaks erinevat HTTP-päringut 127.0.0.1:5000/send/1. Oletame, et niipea kui veebiserver töötleb esimest päringut, peatab CPU selle protsessi ja töötleb teist päringut. Näiteks võib esimene protsess peatada pärast järgmise koodirea käivitamist:
konto.summa = int(konto.summa) - summa
See kood on arvutanud uue kogusumma, kuid pole kirjet veel andmebaasi salvestanud. Kui teine päring algab, teostab see sama arvutuse, lahutab andmebaasis olevast väärtusest 1 dollari (5000 dollarit) ja salvestab tulemuse. Kui esimene protsess jätkub, salvestab see oma väärtuse – 4999 dollarit –, mis ei kajasta konto viimast saldot.
Seega on kaks taotlust täidetud ja kumbki oleks pidanud konto saldost lahutama 1 dollari, mille tulemuseks on uus saldo 4998 dollarit. Kuid olenevalt sellest, millises järjekorras veebiserver neid töötleb, võib lõppkonto saldo olla 4999 dollarit.
Kujutage ette, et saadate viie sekundi jooksul 128 taotlust 1 dollari suuruse ülekande tegemiseks sihtsüsteemi. Selle tehingu tulemusel on eeldatav kontoväljavõte 5000 $ – 128 $ = 4875 $. Kuid võistlustingimuste tõttu võib lõppsaldo varieeruda vahemikus $ 4875 kuni $ 4999.
Programmeerijad on turvalisuse üks olulisemaid komponente
Tarkvaraprojektis on teil programmeerijana üsna palju kohustusi. Ülaltoodud näide oli lihtsa rahaülekande rakenduse jaoks. Kujutage ette, et töötate tarkvaraprojektiga, mis haldab pangakontot või suure e-kaubandussaidi taustaprogrammi.
Peate olema selliste haavatavustega tuttav, et nende kaitsmiseks kirjutatud programm oleks haavatavusest vaba. See nõuab tugevat vastutust.
Rassitingimuste haavatavus on vaid üks neist. Olenemata sellest, millist tehnoloogiat te kasutate, peate jälgima, kas kirjutatavas koodis on haavatavusi. Üks olulisemaid oskusi, mida programmeerijana omandada, on tarkvaraturbe tundmine.