Što znače niti na procesoru? Ukratko na stvar i malo pozadine

Postupak(ili zadatak) je apstrakcija koja opisuje pokrenuti program.

Za OS postupak predstavlja jedinicu rada, zahtjev za potrošnju resursa sustava. Podsustav za upravljanje procesima planira izvođenje procesa, tj. raspodjeljuje procesorsko vrijeme između nekoliko istovremeno postojećih procesa u sustavu, a bavi se i stvaranjem i uništavanjem procesa, opskrbljuje procese potrebnim sistemskim resursima i podržava interakciju između procesa.

Neki se resursi dodjeljuju procesu kada se kreira, a neki se dodjeljuju dinamički na temelju zahtjeva tijekom izvođenja. Resursi se mogu dodijeliti procesu za cijeli život ili samo za određeno razdoblje. Prilikom izvođenja ovih funkcija, podsustav za upravljanje procesima komunicira s drugim OS podsustavima odgovornim za upravljanje resursima, kao što su podsustav za upravljanje memorijom, ulazno/izlazni podsustav i sustav datoteka. Kada se u sustavu istovremeno izvodi nekoliko neovisnih zadataka, nastaju problemi. dodatni problemi. Iako procesi nastaju i izvode se asinkrono, možda će morati međusobno komunicirati, primjerice prilikom razmjene podataka. Usklađivanje brzina procesa također je vrlo važno za sprječavanje uvjeta utrke u kojima više procesa pokušava modificirati istu datoteku, zastoja ili drugih kolizija do kojih dolazi prilikom dijeljenja resursa. Sinkronizacija procesa jedna je od važnih funkcija podsustava za upravljanje procesima.

Svaki put kada proces završi, podsustav za upravljanje procesom zatvara sve datoteke s kojima je proces radio, oslobađajući područja RAM-a dodijeljena za kodove, podatke i sistemske informacijske strukture procesa. Ispravljaju se svi mogući redovi OS i popisi resursa koji sadrže reference na proces koji se prekida.

Da bi podržao multiprogramiranje, OS mora za sebe definirati i dizajnirati one unutarnje jedinice rada između kojih će biti podijeljen procesor i drugi računalni resursi. Mora se podsjetiti da multiprogramiranje je način organiziranja proces računanja, kod kojeg se u memoriji računala nalazi više programa koji se naizmjenično izvršavaju na jednom procesoru.

Trenutno većina operativnih sustava definira dvije vrste jedinica rada. Veća radna jedinica, obično nazvana procesom ili zadatkom, zahtijeva dovršenje nekoliko manjih radova, koji se nazivaju nit ili nit.

Očito, svaka operacija računalnog sustava sastoji se od izvršavanja nekog programa. Stoga je i procesu i dretvi pridružen određeni programski kod koji je za te potrebe dizajniran u obliku izvršnog modula. Da bi se ovaj programski kod mogao izvršiti, mora biti učitan u RAM, možda neki prostor na disku dodijeljen za pohranu podataka, pristup ulazno/izlaznim uređajima, npr. serijski priključak. Tijekom izvođenja, program također može trebati pristup HI, kao što su datoteke. I, naravno, nemoguće je izvršiti program bez da ga imate CPU vrijeme, tj. vrijeme tijekom kojeg procesor izvršava kodove danog programa.

U sustavima u kojima postoje i procesi i dretve, OS proces smatra zahtjevom za potrošnju svih vrsta resursa, osim jednog - procesorskog vremena. Ovaj posljednji najvažniji resurs OS distribuira između ostalih jedinica rada - dretvi, koje su svoje ime dobile po tome što predstavljaju sekvence (niti izvršavanja) naredbi.

U najjednostavnijem slučaju proces se sastoji od jedne niti, tako se pojam “procesa” tumačio sve do sredine 1980-ih, au istom obliku sačuvan je iu nekim suvremenim operativnim sustavima. U sustavima ovog tipa koncept "toka" potpuno je apsorbiran konceptom "procesa", tj. Ostaje samo jedna jedinica rada i potrošnje resursa - proces. Multiprogramiranje se u takvim operacijskim sustavima provodi na razini procesa.

Postoje tri osnovna stanja procesa: spreman, pokrenut i blokiran.

Na jednoprocesorskom sustavu može se izvoditi samo jedan proces. U isto vrijeme može postojati nekoliko spremnih i blokiranih procesa koji čekaju da se dogode neki događaji (na primjer, I/O). U ovom slučaju, popis spremnih procesa poredan je po prioritetu.

Kako bi se spriječilo da procesi ometaju raspodjelu resursa, kao i međusobno oštećivanje kodova i podataka, OS mora odlučiti najvažniji zadatak– izolirati jedan proces od drugog.

Da bi se to postiglo, OS daje svakom procesu zaseban virtualni adresni prostor tako da nijedan proces ne može izravno pristupiti naredbama i podacima drugog procesa.

Obradite virtualni adresni prostor je skup adresa kojima se može manipulirati modulom procesnog programa.

Operativni sustav preslikava virtualni adresni prostor procesa u fizičku memoriju koja mu je dodijeljena.

Kada je potrebna interakcija, procesi se okreću OS-u koji im, djelujući kao posrednik, osigurava sredstva međuprocesne komunikacije – cjevovode, poštanski sandučići, odjeljci zajedničke memorije i neki drugi.

Međutim, u sustavima koji nemaju koncept niti, problemi nastaju kada se organiziraju paralelna izračunavanja unutar procesa. I takva se potreba može pojaviti. Doista, s multiprogramiranjem se povećava propusnost sustavu, ali se zasebni proces nikada ne može izvršiti brže nego u jednoprogramskom načinu rada (svako dijeljenje resursa samo usporava rad jednog od sudionika zbog dodatnog vremena provedenog u čekanju da resurs postane dostupan). Međutim, aplikacija koja se izvodi unutar jednog procesa može imati interni paralelizam, koji bi, u načelu, mogao omogućiti da se njezino rješenje ubrza. Ako, na primjer, program omogućuje pristup vanjskom uređaju, tada je tijekom ove operacije moguće ne blokirati izvršenje cijelog procesa, već nastaviti izračune u drugoj grani programa. Paralelno izvođenje više poslova unutar jedne interaktivne aplikacije poboljšava učinkovitost korisnika. Stoga je pri radu s uređivačem teksta poželjno moći kombinirati upisivanje novog teksta s dugotrajnim operacijama kao što je ponovno formatiranje značajnog dijela teksta, ispis dokumenta ili njegovo spremanje na lokalni ili udaljeni disk.

Niti su se pojavile u OS-u kao sredstvo za paraleliziranje izračuna. Naravno, problem paraleliziranja izračuna unutar jedne aplikacije može se riješiti tradicionalnim metodama.

Prvo, aplikacijski programer može preuzeti složeni zadatak organiziranja paralelizma odabirom određene podrutine dispečera u aplikaciji, koja periodički prenosi kontrolu na jednu ili drugu granu izračuna. U ovom slučaju, program se ispostavlja logički vrlo zbunjujućim, s brojnim prijenosima kontrole, što značajno komplicira njegovo uklanjanje pogrešaka i modificiranje.

Drugo, rješenje je stvoriti nekoliko procesa za svaki od paralelnih poslova za jednu aplikaciju. Međutim, korištenje standardnih OS alata za stvaranje procesa ne dopušta nam da uzmemo u obzir činjenicu da ti procesi rješavaju jedan problem, što znači da imaju mnogo toga zajedničkog jedni s drugima - mogu raditi s istim podacima, koristiti isti kod segmentu, te biti obdareni istim i istim pravima pristupa resursima računalnog sustava.

U OS-u je, uz procese, potreban još jedan mehanizam za paraleliziranje izračuna, koji bi uzeo u obzir bliske veze između pojedinih grana izračuna iste aplikacije.

U te svrhe moderni operacijski sustavi nude mehanizam višenitnosti. Istovremeno se uvodi nova jedinica rada - nit izvršenja a koncept “procesa” u velikoj mjeri mijenja svoje značenje. Koncept "niti" odgovara sekvencijalnom prijelazu procesora s jedne programske instrukcije na drugu. Operativni sustav raspodjeljuje procesorsko vrijeme između niti. OS dodjeljuje adresni prostor i skup resursa procesu koji se dijele među svim njegovim nitima.

U jednoprogramskim sustavima nema potrebe za uvođenjem pojma koji označava jedinicu rada, jer ne postoji problem podjele resursa.

Stvaranje niti zahtijeva manje troškova od OS-a nego procesi. Za razliku od procesa koji pripadaju različitim konkurentskim aplikacijama, sve niti jednog procesa uvijek pripadaju istoj aplikaciji, tako da OS izolira niti u puno manjoj mjeri od procesa u tradicionalnom višeprogramskom sustavu. Sve niti jednog procesa koriste zajedničke datoteke, mjerače vremena, uređaje, isto područje RAM-a i isti adresni prostor. To znači da dijele iste globalne varijable. Budući da svaka nit može pristupiti bilo kojoj virtualnoj adresi procesa, jedna nit može koristiti stog druge niti. Ne postoji potpuna zaštita između dretvi istog procesa, jer, prvo, to je nemoguće, a drugo, nije potrebno. Da bi organizirali interakciju i razmjenu podataka, niti uopće ne moraju pristupati OS-u, samo trebaju koristiti zajedničku memoriju - jedna nit piše podatke, a druga ih čita. S druge strane, teče različite procese još uvijek dobro zaštićeni jedni od drugih.

Multiprogramiranje je učinkovitije na razini niti nego na razini procesa. Svaka nit ima svoj programski brojač i stog. Zadatak dizajniran kao nekoliko niti unutar jednog procesa može se brže izvršiti zahvaljujući pseudoparalelnom (ili paralelnom u višeprocesorskom sustavu) izvršavanju njegovih pojedinačnih dijelova. Multithreading se može posebno učinkovito koristiti za pokretanje distribuiranih aplikacija; na primjer, višenitni poslužitelj može paralelno izvršavati zahtjeve više klijenata.

Korištenje niti je povezano ne samo sa željom da se povećaju performanse sustava putem paralelnog računanja, već i s ciljem stvaranja čitljivijih, logičnijih programa. Uvođenje višestrukih niti izvršavanja pojednostavljuje programiranje. Na primjer, u zadacima pisac-čitač, jedna nit piše u međuspremnik, a druga čita iz njega. Budući da dijele zajednički međuspremnik, ne biste ih trebali raditi odvojeni procesi. Drugi primjer korištenja niti je kontrola signala kao što su prekidi tipkovnice (Del ili Break). Umjesto rukovanja signalom prekida, jedna nit je dodijeljena da stalno čeka da signali stignu. Dakle, korištenje niti može smanjiti potrebu za prekidima na korisničkoj razini. U ovim primjerima, paralelno izvođenje nije toliko važno koliko jasnoća programa.

Najveći učinak od uvođenja višenitne obrade postiže se u višeprocesorskim sustavima, u kojima se niti, uključujući i one koje pripadaju istom procesu, mogu izvršavati na različitim procesorima uistinu paralelno (a ne pseudoparalelno).

Kreirajte proces Prije svega, to znači stvaranje deskriptora procesa, što je jedna ili više informacijskih struktura koje sadrže sve informacije o procesu potrebne OS-u za upravljanje njime. Takve informacije mogu uključivati, na primjer, identifikator procesa, informacije o memorijskoj lokaciji izvršnog modula, stupanj privilegije procesa (prioritet i prava pristupa), itd.

Primjeri deskriptora procesa su Task Control Block (TCB) u OS/360, Process Control Block (PCB) u OS/2, rukovanje procesom u UNIX-u, object-process u Windows NT.

Stvaranje deskriptora procesa označava pojavu još jednog kandidata za računalne resurse u sustavu. Od ove točke nadalje, OS mora uzeti u obzir potrebe novog procesa prilikom dodjele resursa.

Stvaranje procesa uključuje učitavanje kodova i podataka izvršnog programa ovaj proces s diska na RAM. Da bi to učinio, OS mora otkriti mjesto takvog programa na disku, preraspodijeliti RAM i dodijeliti memoriju izvršnom programu novog procesa. Zatim je potrebno pročitati program u za to dodijeljena memorijska područja i, eventualno, promijeniti parametre programa ovisno o mjestu u memoriji.

U sustavima s virtualnom memorijom samo se dio procesnog koda i podataka može učitati u početnom trenutku, kako bi se ostatak „napumpao“ po potrebi. Postoje sustavi u kojima, u fazi kreiranja procesa, nije potrebno nužno učitati kodove i podatke u RAM; umjesto toga, izvršni modul se kopira iz tog direktorija sustav datoteka, u kojem se izvorno nalazio, u zamjensko područje - posebno područje disk dodijeljen za pohranu procesnih kodova i podataka. U izvođenju svih ovih radnji, podsustav za upravljanje procesima blisko je u interakciji s podsustavom za upravljanje memorijom i datotečnim sustavom.

U sustavu s više niti, kada se kreira proces, OS stvara najmanje jednu nit izvršenja za svaki proces. Prilikom kreiranja niti, baš kao i prilikom kreiranja procesa, OS generira posebnu informacijsku strukturu - deskriptor niti, koji sadrži identifikator niti, podatke o pravima pristupa i prioritetu, stanje niti i druge informacije. U početnom stanju, nit (ili proces, ako govorimo o sustavu u kojem pojam "nit" nije definiran) je u suspendiranom stanju. Trenutak odabira niti za izvođenje provodi se u skladu s pravilom za osiguravanje procesorskog vremena prihvaćenim u ovom sustavu i uzimajući u obzir sve postojeće ovaj trenutak niti i procesa. Ako se procesni kodovi i podaci nalaze u swap području, nužan uvjet za aktiviranje procesne niti je i prisutnost prostora u RAM-u za učitavanje izvršnog modula.

Na mnogim sustavima nit može tražiti od OS-a da stvori tzv potomak tokova. Različiti operacijski sustavi različito strukturiraju odnos između niti djece i njihovih roditelja. Na primjer, u nekim operativnim sustavima, izvršavanje nadređene niti sinkronizirano je s njenim potomcima; posebice, nakon završetka nadređene niti, OS može prestati izvršavati sve svoje potomke. Na drugim sustavima, podređene niti mogu se izvršavati asinkrono u odnosu na roditeljsku nit. Potomci obično nasljeđuju mnoga svojstva svojih nadređenih tokova. U mnogim sustavima, stvaranje djece primarni je mehanizam za stvaranje procesa i niti.

Planiranje procesa uključuje rješavanje sljedećih zadataka:

■ određivanje trenutka za promjenu procesa koji se izvodi;

■ odabir procesa za izvršenje iz reda spremnih procesa;

■ promjena konteksta "starih" i "novih" procesa.

Prva dva problema su riješena softver, a potonji se uglavnom temelji na hardveru.

Postoji mnogo različitih algoritama planiranja procesa koji navedene probleme rješavaju na različite načine, teže različitim ciljevima i daju različitu kvalitetu multiprogramiranja. Među ovim skupom algoritama, pogledajmo pobliže dvije skupine najčešćih algoritama: algoritme temeljene na kvantizaciji i algoritme temeljene na prioritetu.

U skladu s algoritmi temeljeni na kvantizaciji, do promjene aktivnog procesa dolazi ako:

■ proces je završio i napustio sustav;

■ došlo je do pogreške;

■ proces je ušao u stanje "čekanja";

■ vremenski odsječak procesora dodijeljen ovom procesu je iscrpljen.

Proces koji je iscrpio svoj kvantum stavlja se u stanje "spreman" i čeka da mu se osigura novi kvantum procesorskog vremena te se odabire za izvršenje prema određenom pravilu. novi proces iz spremnog reda čekanja. Na ovaj način niti jedan proces ne zauzima CPU dugo, zbog čega se kvantizacija široko koristi u sustavima dijeljenja vremena.

Kvantumi dodijeljeni procesima mogu biti isti za sve procese ili različiti. Kvantiteti dodijeljeni jednom procesu mogu biti fiksne vrijednosti ili varirati u različitim razdobljima života procesa. Procesi koji nisu u potpunosti iskoristili kvantum koji im je dodijeljen (na primjer, zbog I/O aktivnosti) mogu ili ne moraju dobiti naknadu u obliku privilegija tijekom naknadnog održavanja. Red čekanja spremnih procesa može se organizirati na različite načine: ciklički, prema pravilu “prvi ušao, prvi izašao” (FIFO) ili prema pravilu “zadnji ušao, prvi izašao” (LIFO).

U algoritmi temeljeni na prioritetima koristi se koncept "prioriteta" procesa.

Prioritet– ovo je broj koji karakterizira stupanj povlaštenosti procesa pri korištenju resursa Računalo, posebice procesorsko vrijeme: što je veći prioritet, veće su privilegije.

Prioritet se može izraziti kao cijeli broj ili razlomak, pozitivne ili negativne vrijednosti. Što su veće privilegije procesa, to će manje vremena provesti u redovima. Prioritet može dodijeliti izravno administrator sustava ovisno o važnosti posla ili plaćenoj naknadi ili ga izračunati sam OS prema određenim pravilima; može ostati fiksan tijekom trajanja procesa ili se mijenjati tijekom vremena u skladu s neki zakon. U potonjem slučaju pozivaju se prioriteti dinamičan.

Postoje dvije vrste algoritama prioriteta: algoritmi koji koriste relativne prioritete i algoritmi koji koriste apsolutne prioritete.

U oba slučaja, odabir procesa za izvršenje iz spremnog reda čekanja provodi se na isti način: odabire se proces s najvišim prioritetom. Problem određivanja trenutka promjene aktivnog procesa rješava se na različite načine. U sustavima relativne prioritete Aktivni proces radi sve dok ne napusti sam procesor, prelazeći u stanje "blokiranja" (ili se pojavi greška, ili se proces prekine). Na sustavima sa apsolutni prioriteti izvođenje aktivnog procesa se prekida pod još jednim uvjetom: ako se u redu čekanja spremnih procesa pojavi proces čiji je prioritet veći od prioriteta aktivnog procesa. U tom slučaju prekinuti proces prelazi u stanje pripravnosti.

U mnogim operativnim sustavima algoritmi za raspoređivanje izgrađeni su korištenjem i kvantizacije i prioriteta. Na primjer, raspoređivanje se temelji na kvantizaciji, ali kvantna vrijednost i (ili) redoslijed kojim se proces odabire iz reda spremnih određuju prioriteti procesa.

Postoje dvije glavne vrste postupaka raspoređivanja procesa: preventivni i nepreemptivni.

Nepreventivni multitasking(Non-preemptive multitasking) je metoda raspoređivanja procesa u kojoj se aktivni proces izvodi sve dok samoinicijativno ne prepusti kontrolu OS planeru tako da on iz reda čekanja odabere drugi proces spreman za pokretanje.

Preventivni multitasking(Preemptive multitasking) je metoda u kojoj odluku o prebacivanju procesora s izvršavanja jednog procesa na izvršavanje drugog donosi OS planer, a ne sam aktivni zadatak.

Pojmovi “preemptivni” i “nepreemptivni” ponekad se poistovjećuju s pojmovima prioritetnih i neprioritetnih disciplina, što je potpuno netočno, kao i s pojmovima apsolutnih i relativnih prioriteta, što je djelomično netočno. Preemptivni i nepreventivni multitasking širi su koncepti od prioritetnih vrsta. Prioriteti zadataka mogu se, ali ne moraju, koristiti iu preventivnim i nepreventivnim metodama raspoređivanja. Dakle, u slučaju korištenja prioriteta, disciplina relativnih prioriteta može se klasificirati kao klasa sustava s nepreventivnim višezadaćnošću, a disciplina apsolutnih prioriteta može se klasificirati kao klasa sustava s preemptivnim višezadaćnošću. Disciplina raspoređivanja bez prioriteta, koja se temelji na dodjeli jednakih vremenskih odsječaka za sve zadatke, odnosi se na preventivne algoritme.

Glavna razlika između preventivnog i nepreventivnog multitaskinga je stupanj centralizacije mehanizma za raspoređivanje zadataka. Na preventivni multitasking mehanizam za raspoređivanje zadataka u potpunosti je koncentriran u OS-u i programer piše svoju aplikaciju bez brige da će se ona izvršavati paralelno s drugim zadacima. U ovom slučaju OS radi sljedeće funkcije: određuje trenutak kada se aktivni zadatak uklanja iz izvršenja, pamti njegov kontekst, odabire iz reda čekanja gotovih zadataka sljedeći i pokreće ga za izvršenje, učitavajući njegov kontekst. Na multitasking bez prevencije Mehanizam raspoređivanja raspoređen je između sustava i aplikacijskih programa. Aplikacijski program, primivši kontrolu od OS-a, sam određuje trenutak završetka svoje sljedeće iteracije i nekim sistemskim pozivom prenosi kontrolu na OS, a OS formira redove zadataka i odabire sljedeći zadatak za izvršenje u skladu s nekim algoritam (na primjer, uzimajući u obzir prioritete) . Ovaj mehanizam stvara probleme i korisnicima i programerima.

Za korisnike to znači da se gubi kontrola nad sustavom na proizvoljno vremensko razdoblje koje određuje aplikacija (a ne korisnik). Ako aplikacija potroši previše vremena obavljajući neki posao, kao što je formatiranje diska, korisnik se ne može prebaciti s tog zadatka na drugi zadatak, kao što je uređivač teksta, dok bi se formatiranje nastavilo u pozadini. Ova situacija je nepoželjna jer korisnici obično ne žele dugo čekati da stroj izvrši svoj zadatak. Stoga programeri aplikacija za preventivno operativno okruženje, preuzimajući funkcije planera, moraju kreirati aplikacije tako da obavljaju svoje zadatke u malim dijelovima. Na primjer, program za formatiranje može formatirati jednu stazu diskete i vratiti kontrolu sustavu. Nakon dovršetka ostalih zadataka, sustav će vratiti kontrolu formateru za formatiranje sljedećeg zapisa. Ova metoda raspodjele vremena između zadataka funkcionira, ali značajno komplicira razvoj programa i postavlja veće zahtjeve za kvalifikacije programera. Programer mora osigurati da je njegov program "prijatelj" prema drugim programima koji se izvode istovremeno s njim, dajući im kontrolu vrlo često. Ekstremna manifestacija "neprijateljstva" aplikacije je njeno zamrzavanje, što dovodi do općeg pada sustava. U sustavima s preventivnim multitaskingom, takve su situacije obično isključene, budući da će središnji mehanizam za planiranje ukloniti zaglavljeni zadatak iz izvršenja.

Međutim, raspodjela funkcija raspoređivača između sustava i aplikacija nije uvijek nedostatak, a pod određenim uvjetima može biti prednost, jer omogućuje programeru aplikacije da dizajnira algoritam raspoređivanja koji je najprikladniji za dani fiksni skup zadataka. Budući da programer sam određuje u programu trenutak u kojem se kontrola vraća, to eliminira neracionalne prekide programa u “nezgodnim” trenucima vremena. Osim toga, problemi dijeljenja podataka lako se rješavaju: zadatak ih koristi isključivo tijekom svake iteracije i uvjeren je da nitko drugi neće promijeniti te podatke tijekom tog razdoblja. Značajna prednost sustava pomaka je više velika brzina prebacivanje sa zadatka na zadatak.

Primjer učinkovite upotrebe non-preemptive multitaskinga je NetWare datotečni poslužitelj, koji je uvelike zahvaljujući tome postigao veliku brzinu rada s datotekama.

Međutim, gotovo svi moderni operacijski sustavi usmjereni na izvršavanje aplikacija visokih performansi (UNIX, Windows NT, OS/2, VAX/VMS) implementiraju preemptive multitasking. Nedavno je došao red na operativne sustave klase stolnih računala. Možda se iz tog razloga često naziva preventivni multitasking pravi.

7 odgovora

Ovo ovisi o hardveru, budući da (možda) ne koristite teoretsko računalo, ali fizički hardver, tako da imate ograničene resurse.

Također, iako možda izvodite 5000+ niti, ovisno o vašem hardveru, to bi moglo biti mnogo sporije od ekvivalentnog programa s 10 niti. Mislim da biste trebali pogledati skupljanje niti.

Obično se broj niti koje se izvode istovremeno određuje brojem procesora i CPU jezgri (uključujući hipernitnost) koje imate. To jest, u bilo kojem trenutku, broj pokrenutih niti (u operativnom sustavu) jednak je broju "jezgri".

Ovisi o tome koliko niti možete pokrenuti istovremeno u svojoj aplikaciji velika količinačimbenici. Najbolji broj(light person) bi bio broj jezgri na stroju, ali naravno kao da se nitko ne pretvara (nema druge aplikacije :).

Da budem iskren, rekao bih da radim puno višenitnosti u .NET/Windows jer osoba obično napravi više "štete" nego koristi kada nema pravog razumijevanja. NET ima koncept skupa niti i trebate znati kako radi uz Windows.

U .NET 3.5/4.0 trebali biste pogledati Task Parallel Library jer je knjižnica mnogo bolja u određivanju koliko niti (ako uopće) treba pokrenuti. S TPL-om skup niti dobiva veliku reviziju i mnogo je pametniji u pogledu umnožavanja niti i krađe zadataka itd. Ali obično radite sa zadacima, a ne s nitima.

Ovo je složeno područje i kao rezultat toga, .NET platforma je uvela Zadatke kako bi programere udaljila od niti i tako omogućila runtimeu da bude pametan u vezi s tim, dok bi programer jednostavno rekao što želi, a ne toliko o tome kako ovaj.

Svaka nit troši više memorije (kernel stog, blok okruženja niti, lokalna nit, stog...). AFAIK nema eksplicitnog ograničenja u sustavu Windows, pa bi ograničenje bila memorija (vjerojatno stog po niti).

U Linux niti više sličnih procesa (dijeljena memorija) i ograničeni ste na:

Cat /proc/sys/kernel/threads-max

Prilično dobro pravilo kada izvodite intenzivne zadatke je da radite isti broj kao i vaš broj fizičkih jezgri.

Da, možete pokrenuti više zadataka, ali oni će čekati resurse (ili niti u skupu niti) i vaš okvir, bez obzira na veličinu, ne može u potpunosti dodijeliti sve glavne CPU resurse na 100% niti zbog pozadine/ drugim procesima. Dakle, što više zadataka stvorite, što više niti stvorite, budući da one brojčano premašuju stvarne moguće paralelne niti (1 po jezgri), to će se više upravljati resursima, čekati u redu i mijenjati.

Test koji smo pokrenuli sada kada radim koristeći predložak virusa za pokretanje dodatne zadatke, pokazalo je da je optimalna razina blizu rezultata procesora kao gornje granice. Zadaci koji se izvode u omjeru jedan prema jedan s fizičkim brojem jezgri trajali su otprilike 1 minutu po zadatku. Postavljeno na udvostručenje CPU brojača, vrijeme zadatka je pošlo s prosječne 1 minute na prosječno 5 minuta za dovršetak. Postaje geometrijski sporiji što više zadataka pokreće kernel.

Na primjer, ako imate 8 fizičkih jezgri, tada bi 8 zadataka trebalo biti najbrže (i korištenjem TPL-a, u biti 8 istovremenih niti u aktivnom procesu). Postoji vaša glavna nit ili proces koji stvara druge zadatke i druge pozadinske procese, ali ako je okvir prilično izoliran radi uživanja u korištenju resursa, oni će biti prilično minimalni.

Površina za programiranje vašeg task cap-a temelji se na brojanju jezgri dok žvakate zadatke iz reda čekanja ili popisa, tako da se aplikacija automatski prilagođava kako postavljate aplikaciju u kutije različitih veličina.

Da bismo to programski definirali koristimo

var CoreCount = System.Environment.ProcessorCount / 2;

Zašto dijeliti s dva, pitate se? Jer gotovo sve moderni procesori koristiti logičke jezgre ili hiperniti. Vlastitim testiranjem trebali biste otkriti da će, ako koristite logično brojanje, vaša ukupna brzina po zadatku, a time i cijeli proces, značajno pasti. Fizičke jezgre su ključ. Nismo mogli vidjeti brz način pronaći fizičko nasuprot logičkom, ali brzi pregled naših kutija pokazalo je da je to dosljedno točno. YMMV, ali ovo može biti prilično brzo.

Mogao sam pokrenuti 4 niti istovremeno na svom trenutnom starom procesoru (2005). Korištenje EVGA CPU snimača prije nego što se oglasio moj CPU zujalica. (Programirano u BIOS izborniku). Vrijednost i premašila je 90 * c. Imajte na umu da govorimo o tokovima podataka koji se izvode istovremeno. dobar primjer bi bilo otvaranje više programa u isto vrijeme. Ali sve u svemu ovisi o tome koliko je vaš procesor dobar u multitaskingu. (drugim riječima, mogu se obraditi mnoge aktivne niti). Na siguran način testiranje je učitati "ocscanner (By EVGA)" i "CPU Thermometer" pomoću CPU-a u OC Scanner. Tijekom testiranja, pazite da vam temperatura ne prijeđe 90*C (ili bilo koju drugu temperaturu na kojoj se osjećate sigurno) i pogledajte trenutni broj niti koje izvodite bacajući na vaš CPU. počnite s 2 niti, pričekajte 3-5 minuta, promatrajući temperaturu CPU-a, dodajte drugu nit, ponovite. (NEMOJTE PRIHVATATI SVOJU SREĆU!!!) (NEMOJTE POKUŠAVATI AKO CPU TERMOMETAR NE MOŽE IZMJERITI VAŠU TEMPERATURU!!!)

  • Tutorial

U ovom ću članku pokušati opisati terminologiju koja se koristi za opisivanje sustava koji mogu paralelno izvršavati nekoliko programa, odnosno višejezgreni, višeprocesorski, višenitni. Različiti tipovi godine pojavio se paralelizam u IA-32 CPU-u drugačije vrijeme i to pomalo nedosljednim redom. Prilično se lako zabuniti u svemu tome, pogotovo ako se uzme u obzir da operativni sustavi pažljivo skrivaju detalje od manje sofisticiranih aplikacijskih programa.

Svrha je članka pokazati da uz svu raznolikost mogućih konfiguracija višeprocesorskih, višejezgrenih i višenitnih sustava, stvaraju se mogućnosti za programe koji se na njima izvode i za apstrakciju (ignoriranje razlika) i za uzimanje u obzir specifičnosti ( mogućnost programskog saznavanja konfiguracije).

Upozorenje o znakovima ®, ™ u članku

Moj komentar objašnjava zašto bi zaposlenici tvrtke trebali koristiti obavijesti o autorskim pravima u javnoj komunikaciji. U ovom članku morao sam ih koristiti prilično često.

CPU

Naravno, najstariji, najčešće korišten i kontroverzan pojam je “procesor”.

U moderni svijet procesor je ono što kupujemo u lijepoj Retail kutiji ili ne tako lijepom OEM pakiranju. Nedjeljiva cjelina umetnuta u utičnicu na matičnoj ploči. Čak i ako nema konektora i ne može se ukloniti, odnosno ako je čvrsto zalemljen, to je jedan čip.

Mobilni sustavi (telefoni, tableti, prijenosna računala) i većina stolnih računala imaju jedan procesor. Radne stanice i poslužitelji ponekad imaju dva ili više procesora na jednoj matičnoj ploči.

Višestruka podrška središnje procesne jedinice u jednom sustavu zahtijeva brojne promjene u njegovom dizajnu. Minimalno je potrebno osigurati njihovu fizičku povezanost (osigurati nekoliko utičnica na matičnoj ploči), riješiti probleme s identifikacijom procesora (vidi dalje u ovom članku, kao i moju prethodnu bilješku), koordinaciju pristupa memoriji i prekid isporuke ( kontroler prekida mora moći usmjeravati prekide za nekoliko procesora) i, naravno, podršku operativnog sustava. Nažalost, nisam uspio pronaći dokumentarni spomen stvaranja prvog višeprocesorskog sustava na Intelovim procesorima, ali Wikipedia tvrdi da ih je Sequent Computer Systems isporučio već 1987., koristeći procesore Intel 80386. Podrška za više čipova u jednom sustavu postaje raširena, počevši od Intel® Pentiuma.

Ako postoji nekoliko procesora, tada svaki od njih ima svoj konektor na ploči. Svaki od njih ima potpune neovisne kopije svih resursa, kao što su registri, izvršni uređaji, predmemorije. Dijele zajedničku memoriju - RAM. Sjećanje se s njima može povezati na različite i prilično netrivijalne načine, ali ovo druga priča, što je izvan dosega ovog članka. Važno je da u svakom slučaju za izvršne programe treba stvoriti iluziju homogene zajedničke memorije kojoj mogu pristupiti svi procesori uključeni u sustav.


Spremni za polijetanje! Intel® ploča za stolna računala D5400XS

Jezgra

Povijesno gledano, više jezgri u Intel IA-32 pojavile su se kasnije od Intel® HyperThreadinga, ali u logičkoj hijerarhiji dolaze sljedeće.

Čini se da ako sustav ima više procesora, njegova je izvedba veća (na zadacima koji mogu koristiti sve resurse). Međutim, ako je cijena komunikacije između njih previsoka, tada se svi dobici od paralelizma uništavaju velikim kašnjenjima za prijenos zajedničkih podataka. To je upravo ono što se opaža kod višeprocesorskih sustava - i fizički i logički su vrlo udaljeni jedni od drugih. Za učinkovita komunikacija U takvim uvjetima potrebno je osmisliti specijalizirane sabirnice, kao što je Intel® QuickPath Interconnect. Potrošnja energije, veličina i cijena konačnog rješenja, naravno, sve to ne umanjuje. Trebalo bi doći u pomoć visoka integracija komponenta - sklopovi koji izvršavaju dijelove paralelni program, morate ih povući bliže jedan drugome, po mogućnosti na jednom kristalu. Drugim riječima, jedan procesor treba organizirati nekoliko jezgre, identične jedna drugoj u svemu, ali rade neovisno.

Prvi višejezgreni IA-32 procesori iz Intela predstavljeni su 2005. godine. Od tada, prosječan broj jezgri na poslužitelju, stolnom računalu i sada mobilne platforme stalno raste.

Za razliku od njih dvoje jednojezgreni procesori U istom sustavu, dijeleći samo memoriju, dvije jezgre također mogu dijeliti predmemorije i druge resurse odgovorne za interakciju s memorijom. Najčešće, predmemorije prve razine ostaju privatne (svaka jezgra ima svoju), dok druga i treća razina mogu biti zajedničke ili odvojene. Ova organizacija sustava omogućuje smanjenje kašnjenja isporuke podataka između susjednih jezgri, posebno ako rade na zajedničkom zadatku.


Mikrografija četverojezgrenog Intel procesora kodnog imena Nehalem. Pojedinačne jezgre su istaknute, dijeljena predmemorija treća razina, kao i QPI veze s drugim procesorima i zajednički memorijski kontroler.

Hipernit

Sve do otprilike 2002. godine, jedini način da se dobije IA-32 sustav koji može paralelno pokretati dva ili više programa bila je upotreba višeprocesorskih sustava. Predstavljen Intel® Pentium® 4 kao i Xeon linija kodnog naziva Foster (Netburst) nova tehnologija- hiperniti ili hiperniti, - Intel® HyperThreading (u daljnjem tekstu HT).

Nema ništa novo pod suncem. HT je poseban slučaj ono što se u literaturi naziva simultanim multithreadingom (SMT). Za razliku od “pravih” jezgri, koje su cjelovite i nezavisne kopije, u slučaju HT-a samo se dio internih čvorova, primarno zaduženih za pohranjivanje arhitektonskog stanja – registara, duplicira u jednom procesoru. Izvršni čvorovi odgovorni za organiziranje i obradu podataka ostaju pojedinačni iu bilo kojem trenutku ih koristi najviše jedna od niti. Kao i jezgre, hiperniti dijele predmemorije, ali od koje razine ovisi o specifičnom sustavu.

Neću pokušavati objasniti sve prednosti i mane SMT dizajna općenito, a posebno HT dizajna. Zainteresirani čitatelj može pronaći prilično detaljnu raspravu o tehnologiji u mnogim izvorima, i, naravno, na Wikipediji. Međutim, primijetit ću sljedeću važnu točku, koja objašnjava trenutna ograničenja broja hiperniti u stvarnim proizvodima.

Ograničenja niti
U kojim slučajevima je opravdana prisutnost "nepravednih" višejezgri u obliku HT-a? Ako jedna nit aplikacije ne može učitati sve izvršne čvorove unutar kernela, tada se oni mogu "posuditi" drugoj niti. To je tipično za aplikacije koje imaju usko grlo ne u računanju, već u pristupu podacima, odnosno često generiraju promašaje predmemorije i moraju čekati da se podaci isporuče iz memorije. Tijekom tog vremena, jezgra bez HT-a bit će prisiljena mirovati. Prisutnost HT-a omogućuje vam brzo prebacivanje slobodnih izvršnih čvorova u drugo arhitektonsko stanje (budući da je duplicirano) i izvršavanje njegovih instrukcija. Ovo je poseban slučaj tehnike koja se naziva skrivanje latencije, kada je jedna duga operacija, tijekom koje korisni resursi miruju, maskirana paralelnim izvršavanjem drugih zadataka. Ako aplikacija već ima visok stupanj iskorištenja resursa kernela, prisutnost hiperniti neće omogućiti ubrzanje - ovdje su potrebni "pošteni" kerneli.

Tipični scenariji za desktop i poslužiteljske aplikacije dizajnirane za strojne arhitekture opće namjene imaju potencijal za paralelizam implementiran pomoću HT-a. Međutim, taj se potencijal brzo troši. Možda iz tog razloga, na gotovo svim IA-32 procesorima broj hardverskih hiperniti ne prelazi dvije. U tipičnim scenarijima, dobit od korištenja tri ili više hiperniti bila bi mala, ali gubitak u veličini matrice, njegovoj potrošnji energije i cijeni je značajan.

Drugačija je situacija u tipičnim zadacima koji se izvode na video akceleratorima. Stoga ove arhitekture karakterizira korištenje SMT tehnologije s većim brojem dretvi. Budući da su koprocesori Intel® Xeon Phi (predstavljeni 2010.) ideološki i genealoški prilično bliski video karticama, možda imaju četiri hipernitnost na svakoj jezgri - konfiguracija jedinstvena za IA-32.

Logički procesor

Od tri opisane "razine" paralelizma (procesori, jezgre, hiperniti), neke ili čak sve mogu nedostajati u određenom sustavu. Ovo je pod utjecajem postavke BIOS-a(multi-core i multi-threading su neovisno onemogućeni), značajke mikroarhitekture (na primjer, HT nije postojao u Intel® Core™ Duo, ali je vraćen s izdavanjem Nehalema) i sistemski događaji (višeprocesorski poslužitelji mogu isključiti neispravni procesori ako se otkriju greške i nastavljaju "letjeti" na preostalima). Kako je ovaj višerazinski zoološki vrt konkurentnosti vidljiv operativnom sustavu i, u konačnici, aplikacijskim aplikacijama?

Nadalje, radi praktičnosti, broj procesora, jezgri i niti u određenom sustavu označavamo s tri ( x, g, z), Gdje x je broj procesora, g- broj jezgri u svakom procesoru, i z- broj hiperniti u svakoj jezgri. Od sada ću ovo zvati tri topologija- ustaljeni termin koji nema mnogo veze s granom matematike. Raditi str = xyz definira broj pozvanih entiteta logički procesori sustava. Definira ukupan broj nezavisnih konteksta procesa aplikacije na sustavu dijeljene memorije, koji se izvode paralelno, koji operacijski sustav prisiljeni uzeti u obzir. Kažem "prisilno" jer ne može kontrolirati redoslijed izvođenja dva procesa na različitim logičkim procesorima. Ovo se također odnosi na hiperniti: iako se izvode "sekvencijalno" na istoj jezgri, određeni redoslijed diktira hardver i programi ga ne mogu promatrati ili kontrolirati.

Najčešće operativni sustav skriva od krajnjih aplikacija značajke fizičke topologije sustava na kojem se izvodi. Na primjer, sljedeće tri topologije: (2, 1, 1), (1, 2, 1) i (1, 1, 2) - OS će ih predstaviti kao dvije logički procesori, iako prvi od njih ima dva procesora, drugi ima dvije jezgre, a treći ima samo dvije niti.


Windows Upravitelj zadataka prikazuje 8 logičkih procesora; ali koliko je to u procesorima, jezgrama i hiperthreadova?


Linux vrh prikazuje 4 logička procesora.

Ovo je prilično zgodno za kreatore aplikacija - ne moraju se baviti hardverskim značajkama koje su im često nevažne.

Softverska definicija topologije

Naravno, apstrahiranje topologije na jedan broj logičkih procesora u nekim slučajevima stvara dovoljno razloga za zabunu i nesporazume (u žestokim internetskim sporovima). Računalne aplikacije koje žele iz hardvera izvući maksimalnu izvedbu zahtijevaju detaljnu kontrolu nad time gdje će njihove niti biti smještene: bliže jedna drugoj na susjednim hipernitima ili, obrnuto, dalje na različitim procesorima. Brzina komunikacije između logičkih procesora unutar iste jezgre ili procesora puno je veća od brzine prijenosa podataka između procesora. Mogućnost heterogenosti u organizaciji radne memorije također komplicira sliku.

Informacije o topologiji sustava u cjelini, kao i položaj svakog logičkog procesora u IA-32, dostupne su pomoću CPUID instrukcije. Od pojave prvih višeprocesorskih sustava, shema identifikacije logičkog procesora je nekoliko puta proširena. Do danas su njegovi dijelovi sadržani u listovima 1, 4 i 11 CPUID-a. Koji list pogledati može se odrediti iz sljedećeg dijagrama toka preuzetog iz članka:

Neću vas ovdje zamarati sa svim detaljima pojedinih dijelova ovog algoritma. Ako bude interesa, sljedeći dio ovog članka može biti posvećen tome. Zainteresiranog čitatelja uputit ću na, koji što detaljnije razmatra ovo pitanje. Ovdje ću prvo ukratko opisati što je APIC i kako se odnosi na topologiju. Zatim ćemo pogledati rad s listom 0xB (jedanaest in decimal), koji je uključen trenutno je zadnja riječ u “apikogradnji”.

APIC ID
Lokalni APIC (napredni programabilni kontroler prekida) je uređaj (sada dio procesora) odgovoran za rukovanje prekidima koji dolaze do određenog logičkog procesora. Svaki logički procesor ima svoj APIC. I svaki od njih u sustavu mora imati jedinstvenu APIC ID vrijednost. Taj broj koriste kontroleri prekida za adresiranje pri isporuci poruka, a svi ostali (na primjer, operativni sustav) za identifikaciju logičkih procesora. Specifikacija za ovaj kontroler prekida evoluirala je od Intel 8259 PIC preko Dual PIC, APIC i xAPIC do x2APIC.

Trenutno je širina broja pohranjenog u APIC ID-u dosegla puna 32 bita, iako je u prošlosti bila ograničena na 16, a još ranije - samo 8 bita. Danas su ostaci starih vremena razasuti po CPUID-u, ali CPUID.0xB.EDX vraća sva 32 bita APIC ID-a. Na svakom logičkom procesoru koji neovisno izvršava CPUID instrukciju, bit će vraćena različita vrijednost.

Razjašnjenje obiteljskih veza
Sama APIC ID vrijednost ne govori vam ništa o topologiji. Da biste saznali koja se dva logička procesora nalaze unutar jednog fizičkog procesora (tj. to su "braća" hiperniti), koja su dva unutar istog procesora, a koji su potpuno različiti procesori, trebate usporediti njihove APIC ID vrijednosti. Ovisno o stupnju odnosa, neki od njihovih bitova će se podudarati. Ove informacije sadržane su u podpopisima CPUID.0xB, koji su operandi kodirani u ECX. Svaki od njih opisuje položaj bitnog polja jedne od topoloških razina u EAX-u (točnije, broj bitova koje treba pomaknuti udesno u APIC ID-u kako bi se uklonili niže razine topologija), kao i tip ovog sloja - hipernit, jezgra ili procesor - u ECX-u.

Logički procesori smješteni unutar iste jezgre imat će iste sve APIC ID bitove, osim onih koji pripadaju SMT polju. Za logičke procesore smještene u istom procesoru, svi bitovi osim Core i SMT polja. Budući da se broj podlistova za CPUID.0xB može povećati, ovu shemu omogućit će nam da podržimo opis topologija s većim brojem razina, ako se ukaže potreba u budućnosti. Štoviše, bit će moguće uvesti međurazine između postojećih.

Važna posljedica organizacije ove sheme je da mogu postojati "rupe" u skupu svih APIC ID-ova svih logičkih procesora u sustavu, tj. neće ići uzastopno. Na primjer, u višejezgrenom procesoru s isključenim HT-om, svi APIC ID-ovi mogu ispasti parni, budući da će najmanji bit odgovoran za kodiranje broja hiperniti uvijek biti nula.

Napominjem da CPUID.0xB nije jedini izvor informacija o logičkim procesorima dostupnim operativnom sustavu. Popis svih procesora koji su mu dostupni, zajedno s njihovim APIC ID vrijednostima, kodiran je u MADT ACPI tablici.

Operacijski sustavi i topologija

Operativni sustavi pružaju informacije o topologiji logičkih procesora aplikacijama koristeći vlastita sučelja.

U Informacije o Linuxu Informacije o topologiji sadržane su u pseudodatoteci /proc/cpuinfo kao iu izlazu naredbe dmidecode. U donjem primjeru filtriram sadržaj cpuinfo na nekom četverojezgrenom sustavu bez HT-a, ostavljajući samo unose koji se odnose na topologiju:

Skriveni tekst

ggg@shadowbox:~$ cat /proc/cpuinfo |grep "procesor\|fizički\ id\|siblings\|core\|cores\|apicid" procesor: 0 fizički id: 0 siblings: 4 jezgre id: 0 cpu jezgre: 2 apicid: 0 početni apicid: 0 procesor: 1 fizički id: 0 braće i sestara: 4 id jezgre: 0 cpu jezgre: 2 apicid: 1 početni apicid: 1 procesor: 2 fizički id: 0 braće i sestara: 4 jezgre id: 1 cpu jezgre: 2 apicid: 2 početni apicid: 2 procesor: 3 fizički id: 0 braća i sestre: 4 id jezgre: 1 cpu jezgre: 2 apicid: 3 početni apicid: 3

Na FreeBSD-u, topologija se prijavljuje putem mehanizma sysctl u varijabli kern.sched.topology_spec kao XML:

Skriveni tekst

korisnik@host:~$ sysctl kern.sched.topology_spec kern.sched.topology_spec: 0, 1, 2, 3, 4, 5, 6, 7 0, 1, 2, 3, 4, 5, 6, 7 0, 1 grupa NITISMT grupa 2, 3 grupa NITISMT grupa 4, 5 grupa NITISMT grupa 6, 7 grupa NITISMT grupa

U MS Windows 8 informacije o topologiji mogu se vidjeti u Task Manageru.

Ovo je četvrti članak u seriji "Probijanje ograničenja sustava Windows", u kojem govorim o ograničenjima koja postoje za temeljne resurse u sustavu Windows. Ovaj put ću s vama razgovarati o ograničenju maksimalnog broja niti i procesa koje podržava Windows. Ovdje ću ukratko opisati razliku između niti i procesa, ograničenje niti ankete, a zatim ćemo govoriti o ograničenjima koja se odnose na proces. Prije svega, odlučio sam govoriti o ograničenjima niti, budući da svaki aktivni proces ima, barem, jedna nit (proces koji je izašao, ali čija je referenca pohranjena u rukovatelju koji pruža drugi proces nema nijednu nit), tako da ograničenja procesa izravno ovise o ograničenjima temeljne niti.

Za razliku od nekih varijanti UNIX-a, većina Windows resursa nema fiksno ograničenje ugrađeno u operativni sustav u vrijeme izgradnje, već su ograničeni na temelju temeljnih resursa dostupnih OS-u, o čemu sam ranije govorio. Procesi i niti, na primjer, zahtijevaju fizičku memoriju, virtualnu memoriju i skupnu memoriju za sebe, tako da je broj procesa i niti koji se mogu stvoriti na danom Windows sustavu u konačnici određen jednim od ovih resursa, ovisno o tome na koji način kreirani su procesi ili niti i koje će od ograničenja temeljnih resursa biti prvo dosegnuto. Stoga vam preporučujem da pročitate moje prethodne članke ako to već niste učinili, jer ću se sljedeći osvrnuti na koncepte kao što su rezervirana memorija, dodijeljena memorija i ograničenje sistemske memorije, o čemu sam govorio u svojim prethodnim člancima:

Procesi i niti
Windows proces je u biti spremnik koji pohranjuje naredbeni kod iz izvršne datoteke. Predstavlja objekt procesa jezgre, a Windows koristi ovaj objekt procesa i njegove povezane podatkovne strukture za pohranu i održavanje informacija o izvršni kod aplikacije. Na primjer, proces ima virtualni adresni prostor u kojem su pohranjeni njegovi privatni i javni podaci i u koji se nalazi izvršna slika i njoj pridružena DLL-ovi. Windows koristi dijagnostičke alate za bilježenje informacija o korištenju resursa procesa kako bi pomogao u praćenju i izvršavanju zahtjeva, te bilježi reference procesa na objekte operacijskog sustava u tablici rukovanja procesom. Procesi rade sa sigurnosnim kontekstom koji se naziva token koji identificira korisnički račun, grupu račun i privilegije dodijeljene procesu.

Proces uključuje jednu ili više niti koje zapravo izvršavaju kod u procesu (tehnički, ne pokreću se procesi, već niti) i predstavljaju se u sustavu kao objekti niti kernela. Postoji nekoliko razloga zašto aplikacije stvaraju niti uz svoju izvornu početnu nit: 1) procesi s korisničkim sučeljem obično stvaraju niti kako bi obavljali svoj posao dok glavna nit odgovara na naredbe korisničkog unosa i upravljanje prozorima; 2) Aplikacije koje žele koristiti više procesora za skaliranje performansi ili koje žele nastaviti raditi dok su niti u zastoju čekajući I/O da se sinkroniziraju, stvaraju niti kako bi iskoristile prednost višenitnosti.

Ograničenja niti
Uz osnovne informacije o niti, uključujući stanje CPU registara, prioritet niti i informacije o upotrebi resursa niti, svaka nit ima dodijeljeni dio adresnog prostora procesa, koji se naziva stog, koji nit može koristiti kao radna memorija tijekom izvođenja programskog koda, za prosljeđivanje parametara funkcije, pohranjivanje lokalnih varijabli i adresa rezultata funkcije. Dakle, kako bi se izbjeglo trošenje virtualne memorije sustava, samo dio stoga se inicijalno dodjeljuje ili se dio prenosi u nit, a ostatak se jednostavno rezervira. Kako memorijski nizovi rastu silaznim redoslijedom, sustav postavlja takozvane "čuvarske stranice" memorije izvan dodijeljenog dijela skupa, koje osiguravaju da se dodatna memorija (zvana proširenje niza) automatski dodjeljuje kada je to potrebno. Sljedeća ilustracija pokazuje kako se dodijeljeno područje stoga produbljuje i kako se zaštitne stranice pomiču kako se stog širi u 32-bitnom adresnom prostoru:

Strukture prijenosnih izvršnih datoteka (PE) izvršnih slika određuju količinu adresnog prostora koji je rezerviran i inicijalno dodijeljen nizu niti. Prema zadanim postavkama, povezivač rezervira 1 MB i dodjeljuje jednu stranicu (4 KB), ali programeri mogu promijeniti ove vrijednosti ili promjenom PE vrijednosti kada komuniciraju sa svojim programom ili pozivanjem funkcije CreateTread na zasebnoj niti. Možete koristiti uslužni program kao što je Dumpbin, koji dolazi s Visual Studiom, za pregled postavki izvršnog programa. Evo rezultata pokretanja Dumpbina s opcijom /headers na izvršnoj datoteci koju je generirao novi Visual Studio projekt:

Pretvaranje brojeva iz heksadecimalni sustav računom, možete vidjeti da je veličina rezerve stoga 1 MB, a dodijeljeno područje memorije 4 KB; korištenjem novi uslužni program od Sysinternals pod nazivom MMap, možete se pridružiti ovom procesu i vidjeti njegov adresni prostor, te tako vidjeti proces izvorno dodijeljenu stranicu steka memorije, stražarsku stranicu i ostatak rezervirane memorije steka:

Budući da svaka nit troši dio adresnog prostora procesa, procesi imaju osnovno ograničenje broja niti koje mogu stvoriti, jednako veličini njihovog adresnog prostora podijeljenoj s veličinom hrpe niti.

Ograničenja 32-bitnih tokova
Čak i ako proces uopće nema kod ili podatke i cijeli adresni prostor može se koristiti za hrpe, 32-bitni proces sa zadanim adresnim prostorom od 2 bajta može stvoriti najviše 2048 niti. Ovo su rezultati rada Testlimit-a na 32-bitnim Windowsima s opcijom -t (stvaranje niti), potvrđujući postojanje ovog ograničenja:

Još jednom, budući da je dio adresnog prostora već bio korišten za kod i početnu hrpu memorije, nije svih 2 GB bilo dostupno za skupove niti, tako da ukupni broj kreiranih niti nije mogao doseći teoretsku granicu od 2048 niti.

Pokušao sam pokrenuti Testlimit s dodatna opcija, koji aplikaciji daje prošireni adresni prostor, nadajući se da ako joj se da više od 2 GB adresnog prostora (na primjer, na 32-bitnim sustavima, to se postiže pokretanjem aplikacije s /3GB ili /USERVA opcijom za pokretanje. ini, ili ekvivalentna BCD opcija na Visti i novijoj riseuserva), koristit će je. 32-bitnim procesima dodijeljeno je 4 GB adresnog prostora kada se izvode na 64-bitnim Windowsima, pa koliko niti može stvoriti 32-bitni Testlimit koji radi na 64-bitnim Windowsima? Na temelju onoga o čemu smo već razgovarali, odgovor bi trebao biti 4096 (4GB podijeljeno s 1MB), ali u praksi je taj broj mnogo manji. Ovdje je 32-bitni Testlimit koji radi na 64-bitnom Windows XP:

Razlog za ovo odstupanje leži u činjenici da kada pokrenete 32-bitnu aplikaciju na 64-bitnom Windowsu, to je zapravo 64-bitni proces koji izvršava 64-bitni kod u ime 32-bitnih niti, te stoga ima po -područja memorije niti rezervirana su za 64-bitne i 32-bitne hrpe niti. Za 64-bitni stog rezervirano je 256 KB (iznimke su operativni sustavi izdani prije Viste, u kojima je početna veličina stoga 64-bitnih niti 1 MB). Budući da svaka 32-bitna nit započinje u 64-bitnom načinu rada, a veličina stoga koja joj se dodjeljuje pri pokretanju veća je od veličine stranice, u većini slučajeva vidjet ćete da je stogu 64-bitne niti dodijeljeno najmanje 16 Kb. Ovdje je primjer 64-bitnog i 32-bitnog niza 32-bitnog toka (32-bitni niz je označen kao "Wow64"):

32-bitni Testlimit uspio je stvoriti 3204 niti na 64-bitnim Windowsima, što se objašnjava činjenicom da svaka nit koristi 1MB + 256KB adresnog prostora za stog (opet, izuzetak je Windows verzije na Vistu, gdje se koristi 1MB+ 1MB). Međutim, dobio sam drugačiji rezultat kada sam pokrenuo 32-bitni Testlimit na 64-bitnom Windows 7:

Razlike između rezultata na sustavima Windows XP i Windows 7 nastaju zbog slučajnije prirode sheme dodjele adresnog prostora u sustavu Windows Vista, nasumične raspodjele izgleda adresnog prostora (ASLR), što dovodi do određene fragmentacije. Nasumično odredite učitavanje DLL-a, stog niti i položaj dinamička memorija, pomaže poboljšati zaštitu od zlonamjernog softvera. Kao što možete vidjeti na sljedećoj snimci programa VMMap, u ispitni sustav Još uvijek je dostupno 357 MB adresnog prostora, ali najveći slobodni blok je 128 KB, što je manje od 1 MB potrebnog za 32-bitni stog:

Kao što sam primijetio, programer može nadjačati zadanu veličinu rezerve stogova. Jedan od mogući razlozi Ovo se može učiniti da se izbjegne gubitak adresnog prostora kada se unaprijed zna da će stog niti uvijek koristiti manje od zadanog 1MB. Testlimit PE slika prema zadanim postavkama koristi rezervnu veličinu stoga od 64KB, a kada navedete opciju -n zajedno s opcijom -t, Testlimit stvara niti s veličinama stogova od 64KB. Ovo je rezultat pokretanja ovog uslužnog programa na sustavu s 32-bitnim Windows XP i 256 MB RAM-a (izvršio sam ovaj test na slab sustav, kako bismo naglasili ovo ograničenje):

Ovdje treba napomenuti da se dogodila još jedna greška, što znači da u ovoj situaciji uzrok nije adresni prostor. Zapravo, hrpe od 64 Kb trebale bi osigurati približno 32 000 niti (2 Gb/64 Kb = 32 768). Dakle, u kojem se ograničenju pojavilo u ovom slučaju? Ako pogledate moguće kandidate, uključujući dodijeljenu memoriju i skup, oni ne daju nikakve naznake u pronalaženju odgovora na ovo pitanje, budući da su sve te vrijednosti ispod njihovih granica:

Odgovor možemo naći u dodatne informacije o memoriji u programu za ispravljanje pogrešaka jezgre, koji će nam pokazati potrebno ograničenje povezano s dostupnom rezidentnom memorijom, čija je cijela količina potrošena:

Dostupna rezidentna memorija je fizička memorija dodijeljena za podatke ili kod koji se moraju nalaziti u RAM-u. Veličine nestraničnog skupa i nestraničnih upravljačkih programa izračunavaju se neovisno, kao što je, na primjer, memorija rezervirana u RAM-u za I/O operacije. Svaka nit ima oba snopa korisničkog načina, kao što sam već govorio, ali oni također imaju snop povlaštenog načina (način jezgre), koji se koristi kada niti rade u načinu jezgre, kao što je izvršavanje sistemskih poziva. Kada je nit aktivna, njezin kernel stog je prikvačen u memoriju tako da nit može izvršiti kod u kernelu za koji možda ne nedostaju potrebne stranice.

Osnovni kernel stog zauzima 12Kb na 32-bitnom Windowsu i 24Kb na 64-bitnom Windowsu. 14225 niti zahtijeva približno 170 MB rezidentne memorije, što je točno količina slobodne memorije na ovom sustavu s onemogućenim Testlimitom:

Nakon što se dosegne ograničenje dostupne sistemske memorije, mnogi osnovne operacije početi kvariti s greškom. Na primjer, evo pogreške koju sam dobio kada sam dvaput kliknuo na prečac Internet Explorer nalazi se na radnoj površini:

Kao što se i očekivalo, radeći na 64-bitnom Windowsu s 256 MB RAM-a, Testlimit je uspio stvoriti 6600 niti - otprilike upola manje niti koje bi mogao stvoriti na 32-bitnom Windowsu s 256 MB RAM-a - prije nego što mu je ponestalo dostupne memorije:

Razlog zbog kojeg sam ranije upotrijebio izraz "osnovni" stog jezgre je taj što nit koja radi grafičke i prozorske funkcije dobiva "veliki" stog kada napravi prvi poziv, što je jednako (ili veće od) 20Kb po 32-bitu Windows i 48Kb na 64-bitnom Windowsu. Testlimit niti ne pozivaju nijedan takav API, tako da imaju osnovne kernel stekove.
Ograničenja 64-bitnih tokova

Kao i 32-bitne niti, 64-bitne niti imaju zadanu rezervu snopa od 1MB, ali 64-bitne niti imaju puno više korisničkog adresnog prostora (8TB), tako da ne bi trebao biti problem kada je u pitanju stvaranje velikog broja niti. Ipak, jasno je da je dostupna rezidentna memorija još uvijek potencijalni limitator. 64-bitna verzija Testlimita (Testlimit64.exe) mogla je stvoriti, sa i bez opcije -n, približno 6600 niti na sustavu sa 64-bitnim Windows XP i 256 MB RAM-a, potpuno isto kao i 32-bitna verzija stvoreno jer je dosegnuto ograničenje rezidentno dostupne memorije. Međutim, na sustavu s 2 GB RAM-a, Testlimit64 je mogao stvoriti samo 55 000 niti, što je znatno manje od broja niti koje bi ovaj uslužni program mogao stvoriti ako bi ograničenje bila rezidentna dostupna memorija (2 GB/24 KB = 89 000):

U ovom slučaju, uzrok je početni stog dodijeljen niti, koji uzrokuje da sustav ostane bez virtualna memorija i pojavljuje se pogreška zbog nedovoljnog kapaciteta stranične datoteke. Jednom kada količina dodijeljene memorije dosegne veličinu RAM-a, brzina stvaranja novih niti se značajno smanjuje jer sustav počinje "kliziti", prethodno stvoreni nizovi niti počinju se straničiti u datoteku stranice kako bi se napravilo mjesta za nove nizove niti, a stranica stranica mora rasti. Uz uključenu opciju -n, rezultati su isti, budući da početna količina dodijeljene memorije steka ostaje ista.

Ograničenja procesa
Broj procesa koje podržava Windows očito bi trebao biti manji od broja niti, jer svaki proces ima jednu nit, a sam proces uzrokuje dodatnu potrošnju resursa. 32-bitni Testlimit koji radi na sustavu sa 64-bitnim Windows XP i 2 GB sistemske memorije stvara oko 8400 procesa:

Ako pogledate rezultat programa za ispravljanje pogrešaka jezgre, postaje jasno da je u ovom slučaju dosegnuto ograničenje rezidentne dostupne memorije:

Ako bi proces koristio rezidentnu dostupnu memoriju za smještaj samo hrpa niti privilegiranog načina rada, Testlimit bi mogao stvoriti mnogo više od 8400 niti na sustavu od 2 GB. Količina rezidentno dostupne memorije na ovom sustavu bez pokretanja Testlimit-a je 1,9 GB:

Dijeljenjem količine rezidentne memorije koju koristi Testlimit (1,9 GB) s brojem procesa koje stvara, nalazimo da svaki proces ima 230 KB rezidentne memorije. Budući da 64-bitni kernel stog zauzima 24 KB, na kraju nam nedostaje približno 206 KB po procesu. Gdje je ostatak iskorištene rezidentne memorije? Kada se kreira proces, Windows rezervira dovoljno fizičke memorije za minimalni radni skup stranica. Ovo se radi kako bi se osiguralo da će proces, u bilo kojoj situaciji, imati dovoljno fizičke memorije na raspolaganju za pohranjivanje količine podataka potrebnih za pružanje minimalnog radnog skupa stranica. Prema zadanim postavkama, veličina radnog skupa stranica često je 200 KB, što se može lako provjeriti dodavanjem stupca Minimalni radni skup u prozoru Process Explorera:

Preostalih 6Kb je rezidentno dostupna memorija, alocirana za dodatnu nonpageable memoriju (od engleskog nonpageable memory), u kojoj je pohranjen sam proces. Proces na 32-bitnom Windowsu koristi nešto manje rezidentne memorije jer je njegov privilegirani niz niti manji.

Kao i kod nizova niti u korisničkom načinu rada, procesi mogu nadjačati svoju zadanu veličinu stranice radnog skupa pomoću funkcije SetProcessWorkingSetSize. Testlimit podržava opciju -n, koja vam u kombinaciji s opcijom -p omogućuje postavljanje minimalne moguće veličine radnog skupa stranica na 80Kb za podređene procese glavnog Testlimit procesa. Budući da podređenim procesima treba vremena da smanje svoje radne skupove stranica, Testlimit, nakon što više ne može pokrenuti procese, pauzira i pokušava nastaviti s radom, dajući svojim podređenim procesima priliku za izvršenje. Testlimit, pokrenut s parametrom -n na sustavu s Windows 7 i 4 GB RAM-a, ima različito ograničenje od rezidentnog ograničenja dostupne memorije - ograničenja dodijeljene memorije sustava:

Na snimci zaslona u nastavku možete vidjeti da alat za ispravljanje pogrešaka jezgre javlja ne samo da je dosegnuto ograničenje dodijeljene sistemske memorije, već i da je, nakon dostizanja tog ograničenja, došlo do tisuća grešaka dodjele memorije, virtualne i memorijske. stranični skup (ograničenje dodijeljene sistemske memorije zapravo je dosegnuto nekoliko puta, jer kada se dogodila pogreška zbog nedostatka kapaciteta datoteke stranice, taj isti volumen se povećao, gurajući ovo ograničenje):

Prije pokretanja Testlimita, prosječna dodjela memorije bila je približno 1,5 GB, tako da su niti zauzimale oko 8 GB dodijeljene memorije. Stoga je svaki proces trošio približno 8 GB/6600 ili 1,2 MB. Izlaz naredbe kernel debugger!vm, koja prikazuje distribuciju vlastito pamćenje(iz engleske privatne memorije) za svaki proces, potvrđuje ispravnost ovog izračuna:

Početna količina memorije dodijeljena nizu niti, opisana ranije, ima mali utjecaj na preostale zahtjeve za dodjelom memorije potrebne za strukture podataka adresnog prostora procesa, unose tablice stranica, unose tablice rukovanja, objekte procesa i niti i vlastite podatke koji proces stvara tijekom svoje inicijalizacije.

Koliko će procesa i niti biti dovoljno?
Dakle, odgovori na pitanja "koliko niti podržava Windows?" i "koliko procesa možete pokrenuti istovremeno u sustavu Windows?" međusobno povezani. Osim nijansi o tome kako niti određuju svoju veličinu hrpe i kako procesi određuju svoj minimalni radni skup stranica, dva glavna faktora koja određuju odgovore na ova pitanja na bilo kojem sustavu su količina fizičke memorije i ograničenje raspodjele sistemske memorije. U svakom slučaju, ako aplikacija stvori dovoljno niti ili procesa da se približi ovim ograničenjima, tada bi njezin programer trebao ponovno razmotriti dizajn te aplikacije, budući da uvijek postoje različiti načini za postizanje istog rezultata s razumnim brojem procesa. Na primjer, glavni cilj pri skaliranju aplikacije je zadržati broj pokrenutih niti jednak broju CPU-a, a jedan od načina da se to postigne je prelazak sa sinkronog I/O na asinkroni korištenjem dovršenih portova, što bi trebalo pomoći u održavanju broj pokrenutih niti u skladu s brojem CPU-a.

U ovom članku ćemo govoriti o temama kao što su procesi i niti, deskriptori procesa, pričajmo o sinkronizacija tokova i dotaknimo se svima omiljenog Windows upravitelj zadataka.

Kroz cijelo postojanje postupak njegovo se izvođenje može više puta prekidati i nastavljati. Za nastavak izvršenja postupak, potrebno je vratiti stanje svog radnog okruženja. Stanje radne okoline prikazuje se stanjem registara i programskog brojača, načinom rada procesora, pokazivačima na otvorene datoteke, informacijama o nedovršenim I/O operacijama, kodovima grešaka sistemskih poziva koje izvodi ovaj proces itd. Ova informacija se zove kontekst procesa.

Da bi OS mogao upravljati procesima mora imati sve potrebne podatke. U tu svrhu pokreće se svaki proces procesna ručka.

Deskriptor – poseban informacijska struktura, koji se pokreće za svaki proces (deskriptor zadatka, kontrolni blok zadatka).

Općenito, deskriptor sadrži sljedeće informacije:

  1. ID procesa.
  2. Tip procesa (ili klasa) koji definira neka pravila za pružanje resursa za nadzornika.
  3. Prioritet procesa.
  4. Varijabla stanja koja određuje u kojem je stanju proces (spreman za rad, radi, čeka I/O uređaj itd.)
  5. Zaštićeno memorijsko područje (ili adresa takve zone) u kojem se pohranjuju trenutne vrijednosti registara procesora ako se proces prekine bez dovršetka rada. Ova informacija se zove kontekst zadatka.
  6. Informacije o resursima koje proces posjeduje i/ili ima pravo koristiti (pokazivači na otvorene datoteke, informacije o I/O operacijama na čekanju, itd.).
  7. Mjesto (ili njegova adresa) za organiziranje komunikacije s drugim procesima.
  8. Parametri vremena pokretanja (točka u vremenu kada se proces treba aktivirati i učestalost ovog postupka).
  9. U nedostatku sustava za upravljanje datotekama, adresa zadatka na disku u njegovom početnom stanju i adresa na disku gdje se istovaruje iz RAM-a ako je zamijenjen drugom.

Ručka procesa U usporedbi s kontekstom, sadrži više operativnih informacija koje bi trebale biti lako dostupne podsustavu za planiranje procesa. Kontekst procesa sadrži manje relevantne informacije i koristi ga operativni sustav tek nakon što se donese odluka o nastavku prekinutog procesa.

Deskriptori, u pravilu se trajno nalaze u RAM-u kako bi se ubrzao rad supervizora koji ih organizira u liste (redove) i prikazuje promjene u stanju procesa pomicanjem odgovarajućeg deskriptora s jedne liste na drugu.

Za svako stanje (osim za stanje rada za jednoprocesorski sustav), OS održava odgovarajući popis zadataka koji su u tom stanju. Međutim, može postojati više od jednog popisa za stanje čekanja, ali onoliko različitih vrsta resursa može uzrokovati stanje čekanja.

Na primjer, može postojati onoliko stanja čekanja za završetak I/O operacije koliko ima I/O uređaja u sustavu.

Procesi i niti

Da bi podržao multiprogramiranje, OS mora za sebe definirati i dizajnirati one unutarnje jedinice rada između kojih će biti podijeljen procesor i drugi računalni resursi. Trenutno većina operativnih sustava definira dvije vrste jedinica rada:

  • Postupak(veća jedinica rada).
  • Teći(nit ili nit) je manja jedinica rada koju proces zahtijeva da završi.
  • Kad govore o procesima, onda žele napomenuti da OS podržava njihovu izolaciju: svaki proces ima vlastiti virtualni adresni prostor, svakom procesu su dodijeljeni vlastiti resursi - datoteke, prozori, itd. Takva izolacija je potrebna kako bi se jedan proces zaštitio od drugog, jer oni, dijeleći sve resurse računalnog sustava, natječu se jedni s drugima.

Općenito procesima jednostavno nisu ni na koji način povezani jedni s drugima i čak mogu pripadati različitim korisnicima koji dijele isto računalni sustav. Drugim riječima, u slučaju procesa, OS ih smatra potpuno nepovezanima i neovisnima. U ovom slučaju, OS je taj koji je odgovoran za natjecanje između procesa za resurse.

Za povećanje brzine procesa moguće je koristiti unutarnji paralelizam u samim procesima. procesima.

Na primjer, neke operacije koje izvodi aplikacija mogu zahtijevati prilično veliku upotrebu CPU-a da bi se dovršile. U tom slučaju, prilikom interaktivnog rada s aplikacijom, korisnik je prisiljen dugo čekati na završetak naručene operacije i ne može kontrolirati aplikaciju dok se operacija ne završi do samog kraja. Takve se situacije događaju prilično često, na primjer, pri obradi velikih slika u grafičkim uređivačima. Ako softverski moduli, obavljanje tako dugotrajnih operacija, trebalo bi formalizirati u obliku neovisnih "podprocesa" ( potoci), koji će se izvršavati paralelno s drugim “potprocesima”, tada korisnik ima priliku paralelno izvoditi nekoliko operacija unutar jedne aplikacije (procesa).

Mogu se razlikovati sljedeće razlike niti iz procesa:

  • OS za niti ne bi trebao organizirati punopravni virtualni stroj.
  • Niti nemaju vlastite resurse, razvijaju se u istom virtualnom adresnom prostoru i mogu koristiti iste datoteke, virtualne uređaje i druge resurse kao dani proces.
  • Jedina stvar koju niti trebaju imati je CPU resurs. Na jednoprocesorskom sustavu, niti dijele procesorsko vrijeme jedna s drugom na isti način kao i normalni procesi, ali na višeprocesorskom sustavu mogu se izvršavati istovremeno ako ne naiđu na konkurenciju zbog pristupa drugim resursima.

Glavna stvar koja osigurava multithreading, je mogućnost paralelnog izvođenja nekoliko vrsta operacija u jednom aplikacijskom programu. Kako se provodi? učinkovito korištenje CPU resursi, a ukupno vrijeme izvršenja zadataka postaje manje.

Na primjer, ako stolni procesor ili program za obradu teksta dizajniran imajući na umu mogućnosti višenitnosti, korisnik može zatražiti ponovno izračunavanje svog radnog lista ili spajanje više dokumenata i istovremeno nastaviti ispunjavati tablicu ili otvoriti sljedeći dokument za uređivanje.

WINDOWS upravitelj zadataka

Upravitelj zadataka prikazuje informacije o programima i procesima izvršavanje na računalu. Tamo također možete vidjeti najčešće korištene metrike performansi procesa.

Upravitelj zadataka služi za prikaz ključnih pokazatelja performansi računala. Za pokrenute programe možete vidjeti njihov status i prekinuti programe koji su prestali reagirati. Možete vidjeti aktivnost pokrenutih procesa koristeći do 15 parametara, kao i grafikone i informacije o upotrebi procesora i memorije.

Osim toga, ako ste spojeni na mrežu, možete vidjeti status mreže i parametre performansi. Ako je na vaše računalo spojeno više korisnika, možete vidjeti njihova imena, koje zadatke obavljaju i poslati im poruku.

Na kartici Procesi prikazuje informacije o procesima koji se izvode na računalu: podatke o CPU-u i upotrebi memorije, brojač procesa i neke druge parametre:

Na kartici Performanse prikazane su informacije o brojaču deskriptora i nitima, memorijskim parametrima:

Trebam unutra sinkronizacija niti javlja se samo u višeprogramskom OS-u i povezan je sa zajedničkim korištenjem hardvera i izvori informacija Računalo. Sinkronizacija je neophodna kako bi se izbjegle trke (pogledajte dolje) i zastoji prilikom razmjene podataka između niti, dijeljenja podataka i kada se pristupa procesoru i I/O uređajima.

Sinkronizacija niti i procesa sastoji se u usklađivanju njihovih brzina obustavom protoka do pojave određenog događaja i njegovim naknadnim aktiviranjem nakon pojave tog događaja.

Zanemarivanje problema sa sinkronizacijom u sustavu s više niti može dovesti do pogrešna odluka zadatke ili čak pad sustava.

Primjer . Zadatak održavanja baze podataka kupaca za određeno poduzeće.

Svaki klijent je dat poseban ulaz u bazi podataka koja sadrži polja Narudžba i Plaćanje. Program koji održava bazu podataka dizajniran je kao jedan proces s nekoliko niti, uključujući:

  • Nit A, koja u bazu podataka unosi podatke o narudžbama primljenim od kupaca.
  • Nit B, koja u bazu podataka bilježi informacije o plaćanjima kupaca za fakture.

Obje ove niti rade zajedno na zajedničkoj datoteci baze podataka koristeći istu vrstu algoritama:

  1. Pročitajte zapis s danim identifikatorom iz datoteke baze podataka u međuspremnik na klijentu.
  2. Unesite novu vrijednost u polje Nalog (za tok A) ili plaćanje (za tok B).
  3. Vratite izmijenjeni zapis u datoteku baze podataka.

Označimo korake 1-3 za tok A kao A1-A3, a za tok B kao B1-B3. Pretpostavimo da u nekom trenutku nit A ažurira polje Narudžba zapisa o kupcu N. Da bi to učinila, čita ovaj zapis u svoj međuspremnik (korak A1), mijenja vrijednost polja Narudžba (korak A2), ali ne imati vremena za dodavanje zapisa u bazu podataka, jer je njegovo izvršenje prekinuto, na primjer, zbog isteka vremenskog odsječka.

Pretpostavimo da je nit B također trebala unijeti podatke o plaćanju u vezi s istim klijentom N. Kada nit B dođe na red, ona uspijeva pročitati unos u svom međuspremniku (korak B1) i ažurirati polje Plaćanje(korak B2) i zatim prekida. Imajte na umu da u međuspremniku toka B postoji zapis o klijentu N, u kojem polje Narudžba ima isto, nepromijenjeno značenje.

Važan koncept sinkronizacija procesa je koncept "kritičnog dijela" programa. Kritični odjeljak je dio programa u kojem se pristupa zajedničkim podacima. Da bi se uklonio učinak uvjeta utrke na resurs, potrebno je osigurati da u bilo kojem trenutku postoji najviše jedan proces u kritičnom odjeljku koji je povezan s tim resursom. Ova tehnika se naziva uzajamno isključivanje.

Najjednostavniji način za provođenje uzajamnog isključivanja je dopustiti procesu u kritičnom odjeljku da onemogući sve prekide. Međutim, ova metoda je neprikladna jer je opasno vjerovati korisničkom procesu da kontrolira sustav; može dugo okupirati procesor, a ako se proces sruši u kritičnom području, cijeli sustav će se srušiti jer prekidi nikada neće biti omogućeni.

Drugi način je korištenje blokirajućih varijabli. Svaki dijeljeni resurs ima pridruženu binarnu varijablu koja ima vrijednost 1 ako je resurs slobodan (to jest, nijedan proces trenutno nije u kritičnom odjeljku pridruženom tom procesu) i vrijednost 0 ako je resurs zauzet. Slika ispod prikazuje fragment algoritma procesa koji koristi varijablu blokiranja F(D) za implementaciju međusobnog isključivanja pristupa zajedničkom resursu D. Prije ulaska u kritičnu sekciju proces provjerava je li slobodan resurs D. Ako je zauzet provjera se ciklički ponavlja, ako je slobodan tada se vrijednost varijable F(D) postavlja na 0, a proces ulazi u kritični dio. Nakon što je proces završio sve operacije sa zajedničkim resursom D, vrijednost varijable F(D) ponovno se postavlja na 1.

Ako su svi procesi napisani prema gore navedenim konvencijama, tada je zajamčeno međusobno isključivanje. Treba napomenuti da operacija provjere i postavljanja blokirajuće varijable mora biti nedjeljiva. Ovo je objašnjeno na sljedeći način. Pretpostavimo da je, kao rezultat provjere varijable, proces utvrdio da je resurs slobodan, ali je odmah nakon toga, bez vremena za postavljanje varijable na 0, prekinut. Dok je bio obustavljen, drugi je proces zauzeo resurs, ušao u njegov kritični odjeljak, ali je također prekinut bez dovršetka rada s dijeljenim resursom. Kada je kontrola vraćena prvom procesu, on je, smatrajući resurs slobodnim, postavio znak zauzetosti i započeo izvršavanje svoje kritične dionice. Time je prekršeno načelo međusobnog isključivanja, što potencijalno može dovesti do neželjenih posljedica. Kako biste izbjegli takve situacije, preporučljivo je imati jednu naredbu "provjeri-instaliraj" u sustavu naredbi stroja ili implementirati sustavna sredstva odgovarajuće softverske primitive koje bi onemogućile prekide tijekom cijele operacije provjere i instalacije.

Implementacija kritičnih odjeljaka pomoću varijabli za blokiranje ima značajan nedostatak: tijekom vremena dok je jedan proces u kritičnom odjeljku, drugi proces koji zahtijeva isti resurs će se izvršavati rutinske aktivnosti ispitivanjem blokirajuće varijable, gubeći procesorsko vrijeme. Za otklanjanje takvih situacija može se koristiti tzv. aparat događaja. Ovaj se alat može koristiti za rješavanje ne samo problema međusobnog isključivanja, već i općenitijih problema sinkronizacije procesa. U različitim operativnim sustavima, aparat događaja implementiran je na svoj način, ali u svakom slučaju koriste se sistemske funkcije slične namjene, koje se konvencionalno nazivaju WAIT(x) i POST(x), gdje je x identifikator nekog događaj.

Ako je resurs zauzet, tada proces ne provodi cikličko prozivanje, već poziva sistemsku funkciju WAIT(D), ovdje D označava događaj kada je resurs D oslobođen. Funkcija WAIT(D) stavlja aktivni proces u stanje WAITING te u svom deskriptoru zapisuje da proces čeka događaj D. Proces koji trenutno koristi resurs D nakon izlaska iz kritične sekcije izvršava POST(D) sistemsku funkciju, uslijed čega operativni sustav skenira red čekanja procesa i stavlja proces koji čeka događaj D u stanje SPREMAN.

Opći način sinkronizacije procesa predložio je Dijkstra, koji je uveo dvije nove primitive. U apstraktnom obliku, ove primitive, označene P i V, djeluju na nenegativnim cijelim varijablama tzv. semafori. Neka je S takav semafor. Operacije su definirane na sljedeći način:

V(S): varijabla S se povećava za 1 s jednom nedjeljivom radnjom; dohvaćanje, povećanje i pohranjivanje ne mogu se prekinuti, a S-u ne pristupaju drugi procesi dok je ova operacija u tijeku.

P(S): Smanjuje S za 1 ako je moguće. Ako je S=0, tada je nemoguće smanjiti S i ostati u području nenegativnih cijelih vrijednosti, u kojem slučaju proces koji poziva P operaciju čeka dok to smanjenje ne postane moguće. Uspješna provjera i redukcija također je nedjeljiva operacija.

U posebnom slučaju kada semafor S može uzeti samo vrijednosti 0 i 1, pretvara se u blokirajuću varijablu. P operacija ima potencijal staviti proces koji je izvršava u stanje čekanja, dok V operacija može, pod nekim okolnostima, aktivirati drugi proces koji je obustavljen P operacijom.

Zastoj procesa

Prilikom organiziranja paralelnog izvođenja nekoliko procesa, jedna od glavnih funkcija OS-a je pravilna raspodjela resursa između pokrenutih procesa i osiguravanje procesa sredstvima međusobne sinkronizacije i razmjene podataka.

Prilikom paralelnog izvođenja procesa može doći do situacija u kojima su dva ili više procesa cijelo vrijeme blokirani. Najjednostavniji slučaj je kada svaki od dva procesa čeka na resurs koji je zauzeo drugi proces. Zbog ovog čekanja niti jedan proces ne može nastaviti s izvođenjem i eventualno osloboditi resurs koji je potreban drugom procesu. Ovaj zastoj se zove zastoj(mrtva brava) slijepa ulica, klinč ili zastoj.

U višezadaćnom sustavu za proces se kaže da je u mrtvoj točki ako čeka na događaj koji se nikada neće dogoditi.

Treba razlikovati situacije od zastoja jednostavni redovi čekanja, iako se oba pojavljuju kada se resursi dijele i izgledaju slično: proces je obustavljen i čeka da se resurs oslobodi. Međutim, red je normalan i inherentan je znak visoke iskorištenosti resursa kada zahtjevi stignu nasumično. Javlja se kada resurs trenutno nije dostupan, ali nakon nekog vremena se oslobađa, a proces nastavlja svoje izvršavanje. Zastoj je donekle nerješiva ​​situacija.

Problem zastoja uključuje sljedeće zadatke:

  1. sprječavanje zastoja.
  2. prepoznavanje zastoja.
  3. vraćanje sustava nakon zastoja.

Zastoj se može spriječiti u fazi pisanja programa, odnosno programi moraju biti napisani tako da do zastoja ne može doći ni pod kojim omjerom međusobnih brzina procesa. Dakle, ako su u prethodnom primjeru proces A i proces B zatražili resurse u istom nizu, tada bi zastoj bio nemoguć u načelu. Drugi pristup sprječavanju zastoja naziva se dinamički i uključuje korištenje određenih pravila prilikom dodjele resursa procesima, na primjer, resursi se mogu dodijeliti u određenom slijedu koji je zajednički svim procesima.

U nekim slučajevima, kada se zastoj pojavi među mnogim procesima koji koriste mnogo resursa, prepoznavanje zastoja nije trivijalan zadatak. Postoje formalne, softverski implementirane metode za prepoznavanje zastoja, temeljene na održavanju tablica dodjele resursa i tablica upita za zauzete resurse. Analiza ovih tablica omogućuje otkrivanje zastoja.

Ako dođe do situacije zastoja, tada nije potrebno ukloniti sve blokirane procese iz izvršenja. Možete ukloniti samo dio njih, čime se oslobađaju resursi koje očekuju drugi procesi, neke procese možete vratiti u swap područje, neke procese možete “vratiti” u tzv. kontrolnu točku, koja pohranjuje sve informacije potrebne za vraćanje izvođenje programa iz ovo mjesto. Kontrolne točke postavljaju se u program na mjesta nakon kojih može doći do zastoja.