Salam! Meniň adym Kiril Famin, men bolsa iOS dörediji.
Bu makalada Grand Central Dispatch (GCD) -ni bir gezek açarys. “Swift Modern Concurrency” -iň barlygy sebäpli GCD köne ýaly görünse-de, bu çarçuwany ulanýan kod köp ýyllap önümçilikde-de, söhbetdeşliklerde-de peýda bolar.
Bu gün diňe GCD-iň esasy düşünjesine ünsi jemläris. Diňe köp okamagyň möhüm taraplaryny jikme-jik öwreneris, nobatlaryň we sapaklaryň arasyndaky baglanyşygy - beýleki köp makalalaryň ünsden düşürýän mowzugy. Bu düşünjeleri göz öňünde tutup, DispatchGroup
, DispatchBarrier
, semafor, mutex we ş.m. ýaly mowzuklara düşünmek has aňsat bolar.
Bu makala täze başlanlar we tejribeli işläp düzüjiler üçin peýdaly bolar. Tehniki adalgalaryň aşa köp bolmagynyň öňüni alyp, hemme zady düşnükli dilde düşündirmäge synanyşaryn.
Mazmuna syn
- Esasy düşünjeler: sapak, köp okamak, GCD, wezipe, nobat
- Nobatlaryň görnüşleri: esasy, global, adat
- Nobatyň ileri tutulýan ugurlary: Hyzmatyň hili (QoS)
- Seriýa we yzygiderli nobatlar
- Wezipeleri ýerine ýetirmegiň ýollary: async, sinhronlamak
- Gulp
- GCD maşklary
- Salgylar
Esasy düşünjeler: sapak, köp okamak, GCD, wezipe we nobat
Tekst - esasan, ulgam görkezmeleriniň toplumy ýerleşdirilen we ýerine ýetirilýän gap. Aslynda, ýerine ýetirip boljak kodlaryň hemmesi käbir sapaklarda işleýär. Esasy sapak bilen işçi sapaklaryny tapawutlandyrýarys.
Köp okamak - ulgamyň birnäçe sapagy bir wagtda ýerine ýetirmek ukyby (şol bir wagtyň özünde). Bu koduň birnäçe şahasyna parallel işlemäge mümkinçilik berýär.
“Grand Central Dispatch” (GCD) - sapaklar bilen işlemegi ýeňilleşdirýän çarçuwa (köp okamagyň artykmaçlyklaryndan peýdalanmak). Onuň esasy başlangyçlary meseleler we nobatlar.
Şeýlelik bilen, GCD şol bir wagtyň özünde ýerine ýetirýän kod ýazmagy aňsatlaşdyrýan guraldyr. Simpleönekeý mysal, esasy sapakdaky UI täzelenmelerine päsgel bermezlik üçin agyr hasaplamalary aýratyn sapaga ýüklemekdir.
Wezipe - dörediji tarapyndan toparlanan görkezmeler toplumy. Haýsy koduň belli bir meselä degişlidigini döredijiniň çözýändigine düşünmek möhümdir.
Mysal üçin:
print(“GCD”) // a task
let database = Database() let person = Person(age: 23) // also a task database.store(person)
Nobat - GCD-iň esasy başlangyjy, işläp düzüjiniň ýerine ýetirmek üçin wezipeleri goýýan ýeri. Nobat sapaklaryň arasynda meseleleri paýlamak jogapkärçiligini öz üstüne alýar (her nobat ulgamyň sapak howzuna girip biler).
Aslynda, nobatlar sapaklary gönüden-göni dolandyrmak däl-de, kodlaryňyzy meselelere tertipleşdirmäge ünsi jemlemäge mümkinçilik berýär. Bir meseläni nobata ibereniňizde, elýeterli sapakda ýerine ýetiriler - köplenç ýumuş ibermek üçin ulanylýanlardan tapawutly.
Ghli GIF-leriň mp4 wersiýalaryny tapyp bilersiňiz
Nobatlaryň görnüşleri
Esasy nobat - diňe esasy sapakda ýerine ýetirilýän nobat. Bu serial (has soňrak).
let mainQueue = DispatchQueue.main
Global nobatlar - ulgam tarapyndan üpjün edilýän 5 nobat (her ileri tutulýan dereje üçin bir) bar. Olar birmeňzeş.
let globalQueue = DispatchQueue.global()
Omörite nobatlar - dörediji tarapyndan döredilen nobatlar. Öndüriji 5 ileri tutulýan ugurdan birini we görnüşini saýlaýar: yzygiderli ýa-da yzygiderli (tertip boýunça olar seriýal).
let userQueue = DispatchQueue(label: “com.kirylfamin.concurrent”, attributes: .concurrent).
Ileri tutulýan ugurlar
Hyzmatyň hili (QoS) - nobatyň ileri tutulýan ulgamy. Bir meseläniň ýerine ýetirilýän nobatynyň ähmiýeti näçe ýokary bolsa, şonça-da köp serişde bölünip berilýär. Jemi 5 QoS derejesi bar:
.userInteractive
- iň ýokary ähmiýet. Derrew ýerine ýetirilmegini talap edýän, ýöne esasy sapakda işlemek üçin laýyk däl meseleler üçin ulanylýar. Mysal üçin, hakyky wagtda surata düşürmäge mümkinçilik berýän programmada, retouch netijesi derrew hasaplanmalydyr; şeýle-de bolsa, esasy sapakda edilse, UI täzelenmelerine we elmydama esasy sapakda bolup geçýän hereketlere päsgel berer (mysal üçin, ulanyjy barmaly ýeriniň üstünden barmagyny süýşürende we programma derrew netijäni “barmagyň aşagynda” görkezmeli). Şeýlelik bilen, esasy sapagy ýüklemän netijäni mümkin boldugyça çalt alýarys.
.userInitiated
- interaktiw meseleler ýaly möhüm bolmasa-da, çalt seslenmegi talap edýän meseleler üçin ileri tutulýan ugur. Adatça, ulanyjy meseläniň bada-bat gutarmajakdygyna we garaşmaly boljakdygyna düşünýän meseleler üçin ulanylýar (mysal üçin, serwer haýyşy).
.default
- adaty ileri tutulýan ugur. Dörediji nobat döredilende QoS-ny kesgitlemeýän bolsa - ýumuş üçin anyk talaplar ýok bolsa we onuň ähmiýetini kontekstden kesgitläp bolmaýan bolsa (meselem, .userInitiated ileri tutulýan nobat bilen bir meseläni çagyrsaňyz, wezipe şol ileri tutulýar).
.utility
- ulanyjylaryň derrew seslenmegini talap etmeýän, ýöne programmanyň işlemegi üçin zerur bolan meseleler üçin ileri tutulýan ugur. Mysal üçin, maglumatlary serwer bilen sinhronlamak ýa-da diska awtosawka ýazmak.
.background
- iň pes ähmiýet. Mysal üçin keş keşini arassalamak.
Quhli nobatlar Serial nobatlar ýa-da yzygiderli nobatlar hökmünde bölünýär
Seriýa nobatlary - adyndan görnüşi ýaly, bular wezipeleriň biri-birini ýerine ýetirýän nobatlarydyr. Bu, indiki meseläniň diňe häzirki iş gutarandan soň başlanýandygyny aňladýar.
Bilelikdäki nobatlar - Bu nobatlar meseleleri paralel ýerine ýetirmäge mümkinçilik berýär - öňki meseleler gutarandygyna garamazdan çeşmeler bölünen badyna täze mesele başlaýar. Diňe başlangyç sargyt kepillendirilendigine üns beriň (ozal berlen mesele soňkusyndan öň başlar ), ýöne gutarmagyň tertibi kepillendirilmeýär.
Wezipeleri nädip ýerine ýetirmeli
Çagyryş sapagy bilen baglanyşykly meseleleriň ýerine ýetiriş usullaryny ara alyp maslahatlaşýandygymyzy bellemelidiris. Başga sözler bilen aýdylanda, ýumuş diýmegiň usuly, meseläni nobata iberýän sapakda wakalaryň nähili bolýandygyny kesgitleýär.
Asynkron görnüşde ( async
)
Asynkron jaň, çagyryş sapagynyň petiklenmedik ýeridir, ýagny ýerine ýetirýän işine garaşmaýar.
DispatchQueue.main.async { print(“A”) } print(“B”)
Bu mysalda, esasy sapakdan esasy nobata print("A")
meselesini birkemsiz ýerine ýetirýäris (bu kod belli bir nobatyň içinde bolmansoň, esasy sapakda ýerine ýetirilýär). Şeýlelik bilen, esasy sapakdaky meselä garaşmaýarys we derrew ýerine ýetirilmegini dowam etdirýäris. Bu aýratyn mysalda print("A")
meselesi esasy nobata ýazylýar we soňra print("B")
esasy sapakda derrew ýerine ýetirilýär. Esasy sapak häzirki kody ýerine ýetirmek bilen meşgullanýandygy sebäpli (we esasy nobatdaky meseleler diňe esasy sapakda ýerine ýetirilip bilner), häzirki ýumuş print("B")
ilki bilen gutarýar we diňe esasy sapak boş bolansoň, esasy nobat meselesi print("A")
işleýär. Çykyş: BA.
DispatchQueue.global().async { updateData() DispatchQueue.main.async { updateInterface() } Logger.log(.success) } indicateLoading()
Biz esasy sapakdan deslapky ähmiýeti bilen global nobata birkemsiz goşýarys - şonuň üçin jaň sapagy derrew dowam edýär we
indicateLoading()
.
Birneme wagt geçensoň, ulgam ýumuş üçin çeşmeler bölýär we sapak basseýninden mugt işçi sapagynda ýerine ýetirýär we
updateData()
diýilýär.
updateInterface()
öz içine alýan mesele esasy nobata asynkron görnüşde berilýär - jaň edýän işçi sapagy gutarmagyna garaşmaýar we dowam edýär.
Işler birkemsiz ýerine ýetirilendigi sebäpli, çeşmeleriň haçan bölünjekdigini anyk bilip bilmeris. Bu ýagdaýda,
updateInterface()
(esasy sapakda) ýa-daLogger.log(.success)
(işçi sapagynda) ilki ýerine ýetiriljekdigini anyk aýdyp bilmeris (1-2-nji ädimde edip bilmeris: ilki ýerine ýetirýän, esasy sapakdaindicateLoading()
ýa-da işçi sapagyndaDataupdateData()
). Esasy sapak UI täzelenmeleri, jestleri gaýtadan işlemek we beýleki esasy meseleler bilen meşgul bolsa-da, elmydama iň ýokary ulgam çeşmelerini alýar. Beýleki tarapdan, işçi sapagynda ýerine ýetirmek üçin çeşmeler derrew diýen ýaly bölünip bilner.
Bu animasiýada global nobatyň käbir mugt işçi sapaklarynda öz wezipelerini ýerine ýetirýändigini ýadyňyzdan çykarmaň
Sinhron ( sync
)
Sinhron jaň, çagyryş sapagynyň durup, nobatda ýerine ýetirilen işine garaşýan ýeridir.
let userQueue = DispatchQueue(label: "com.kirylfamin.serial") DispatchQueue.global().async { var account = BankAccount() userQueue.sync { account.balance += 10 } let balance = account.balance print(balance) }
Bu ýerde, global nobatda bir meseläni ýerine ýetirýän işçi sapagyndan, deňagramlylygy ýokarlandyrmak üçin adaty nobatda bir meseläni sinhronlaşdyrýarys. Häzirki sapak petiklenýär we berlen işiň gutarmagyna garaşýar. Şeýlelik bilen, balans diňe adaty nobatdaky wezipe artdyrylandan soň çap edilýär.
Bellik: aboveokardaky animasiýada adaty nobat käbir mugt işçi sapaklarynda öz wezipelerini ýerine ýetirýär
Gulp
Sinhron meseleleriň çäginde, sapak ýa-da sapaklar özleri ýa-da biri-biriniň dowam etmegi üçin belli bir wagt garaşmasa, petiklemäni ara alyp maslahatlaşmak möhümdir. Iň ýaýran mysal, esasy sapakdan DispatchQueue.main.sync {calling diýmekdir.
Esasy sapak , käbir kodlary sinhron ýerine ýetirmek isleýän häzirki meseläni ýerine ýetirmek bilen meşgullanýar. Şeýlelik bilen, sinhron jaň esasy sapagy bloklaýar. Esasy ýumuş ýerine ýetirilýär, ýöne başlap bilmeýär, sebäbi häzirki işiň gutarmagyna garaşýan esasy sapak petiklenýär we esasy nobatdaky meseleler diňe esasy sapakda bolup biler. Ilki bilen göz öňüne getirmek kyn bolup biler, ýöne esasy zat DispatchQueue.main.sync
bilen berlen meseläniň häzirki meseläniň bir bölegine öwrülýändigine düşünmek we häzirki işden soň nobata durýarys. Netijede, sapak häzirki ýumuş bilen meşgullanýanlygy sebäpli, başlap bolmajak bir bölegine garaşýar.
func printing() { print(“A”) DispatchQueue.main.sync { print(“B”) } print(“C”) }
Esasy nobatdaky print("B")
ýerine ýetirip bilmejekdigine üns beriň, sebäbi esasy sapak petiklenendir.
GCD maşklary
Bu bölümde şu wagta çenli alnan ähli bilimler bilen dürli çylşyrymly maşklary ara alyp maslahatlaşarys: söhbetdeşliklerde duşjak ýönekeý kod bloklaryndan başlap, şol bir wagtyň özünde programmirlemäge düşünmegiňizi güýçlendirýän öňdebaryjy kynçylyklara çenli. Bu meseleleriň hemmesinde sorag: Konsolda näme çap ediler?
Esasy nobatyň yzygiderli, global () nobatlaryň birmeňzeşdigini ýadyňyzdan çykarmaň, käwagt mesele belli bir atributlary bolan adaty nobatlary öz içine alyp biler.
Esasy maşklar
Adaty kynçylyklardan - çykyşda näbellilik mümkinçiligi az bolanlardan başlarys. Bu meseleler, söhbetdeşliklerde ýüze çykmagy ähtimal; esasy zat wagtyňyzy almak we meseläni üns bilen seljermekdir.
Exerciseshli maşklaryň doly koduny şu ýerden tapyp bilersiňiz.
1-nji wezipe
print(“A”) DispatchQueue.main.async { print(“B”) } print(“C”)
- Esasy sapakda
print("A")
ýerine ýetirilýär. -
print("B")
esasy nobata asynkron görnüşde berilýär. Esasy sapak meşgul bolansoň, bu mesele nobata garaşýar. - Esasy sapakda
print("C")
ýerine ýetirilýär. - Esasy sapak mugt bolanda (öňki ýumuş gutarandan soň, diňe UI täzelenmeleri, jest bilen işlemek we ş.m. ýaly esasy nobatdaky meseleler däl-de, esasy sapakda gaýtadan işlenmeli beýleki wakalar bolup biler. Has çuňňur düşünmek üçin, “RunLoop ” hakda has giňişleýin okaň) berlen iş
print("B")
.
Jogap : ACB
2-nji wezipe
print(“A”) DispatchQueue.main.async { print(“B”) } DispatchQueue.main.async { print(“C”) } print(“D”)
- Esasy sapakda
print("A")
ýerine ýetirilýär. -
print("B")
esasy nobata ýazylýar. Esasy sapak elýeterli bolýança esasy nobat. -
print("C")
çap edilenden soň berilýär ("B") we garaşýar. - Esasy sapak ýerine ýetirilmegini dowam etdirýär we "D" çap edýär.
- Esasy sapak elýeterli bolanda (beýleki RunLoop meselelerini ýerine ýetireniňizden soň), birinji nobatdaky amal
print("B")
ýerine ýetirilýär. - Esasy sapak täzeden erkin bolansoň (beýleki RunLoop meselelerini ýerine ýetirenimden soň - geljekde bu jikme-jigi umumy tertibe täsir etmeýänligi üçin goýaryn),
print("C")
.
Jogap : ADBC
Käbir mysallarda düşündirişi birneme ýönekeýleşdirjekdigimi we ulgamyň sinhron jaňlaryň ýerine ýetirilişini optimallaşdyrýandygyny, soňrak ara alyp maslahatlaşjakdygymy ýatdan çykarmaly däl.
3-nji wezipe
print(“A”) DispatchQueue.main.async { // 1 print(“B”) DispatchQueue.main.async { print(“C”) } DispatchQueue.global().sync { print(“D”) } DispatchQueue.main.sync { // 2 print(“E”) } } // 3 print(“F”) DispatchQueue.main.async { print(“G”) }
-
print("A")
esasy sapakda ýerine ýetirilýär. - Asynkron mesele (1–3 belgili) häzirki (esasy) sapagy ýapmazdan esasy nobata ýazylýar.
- Esasy sapak ýerine ýetirilmegini dowam etdirýär we
"F"
çap edýär. -
print("G")
amaly, öňki ýumuşdan soň (1–3 ädimler) esasy nobata ýazylýar. - Esasy sapak erkin bolansoň, birinji nobatdaky amal -
print("B")
ýerine ýetirilýär. -
print("C")
soňra esasy nobata ýazylýar (häzirki wezipe henizem ýerine ýetirilýär weprint("G")
nobatda durýar). Asynhron görnüşde goşulandygy sebäpli, ýerine ýetirilmegine garaşmaýarys we derrew dowam edýäris. - Ondan soň,
print("D")
operasiýasy global nobata ýazylýar. Bu çagyryş sinhron bolany üçin, dowam etmezden ozal global nobat ýerine ýetirilýänçä garaşýarys (islendik işçi sapagynda işlemegi mümkin). - Ahyrynda
print("E")
amaly esasy nobata ýazylýar. Bu jaň sinhron bolansoň, häzirki sapak ýumuş gutarýança petiklenmeli. Şeýle-de bolsa, esasy nobatda eýýäm meseleler bar weprint("E")
amaly soňundan soň goşulýar. Şol sebäpli, bu amallarprint("E")
. Mainöne esasy sapak häzirki amaly ýerine ýetirmek bilen meşgullanýar, şonuň üçin indiki nobatdaky amallara geçip bilmez. Häzirki amaldan soň"G"
we"C"
çap etmek üçin hiç hili amal bolmasa-da, häzirki amal (1-3 ädimler) entek gutarmansoň, sapak dowam edip bilmedi.
- Çagyryş birkemsiz bolan bolsa,
"G"
we"C"
çap etmek amallaryndan soň çap etmek ("E") amal ediler.
Jogap : AFBD
Alternatiw jogap (ikinji jaň async
bolan bolsa): AFBDGCE
4-nji wezipe
let serialQueue = DispatchQueue(label: “com.kirylfamin.serial”) serialQueue.async { // 1 print(“A”) serialQueue.sync { print(“B”) } print(“C”) } // 2
Bir mesele (1-2 ädimler) adaty seriýa nobatynda asynkron görnüşde berilýär (tertip boýunça
.concurrent
atributyny ulanmaýandygymyz üçin nobatlar yzygiderli).- Ulgam serişdeleri bölüp berende, ýerine ýetiriş başlaýar we
"A"
çap edilýär. - Şol bir yzygiderli nobatda,
print("B")
berilýär. Çagyryş sinhron bolany üçin, ýerine ýetirilmegine garaşýan sapak bloklary. - Şeýle-de bolsa, nobat yzygiderli we daşarky 1-2 iş bilen meşgul bolansoň,
print("B")
işi başlap bilmez, netijede petiklener.
Jogap : A, petik
Bu mysal, esasy nobat bolsun ýa-da adaty bir nobat bolsun, islendik nobatda nobatyň bolup biljekdigini görkezýär.
5-nji wezipe
Öňki ýumuşdan yzygiderli nobaty yzygiderli ýerine çalyşalyň.
DispatchQueue.global().async { // 1 print("A") DispatchQueue.global().sync { print("B") } print("C") } // 2
- Bir mesele (1-2 ädim) global (yzygiderli) nobatda asynkron görnüşde berilýär.
- Çeşmeler bölünende ýerine ýetiriş başlaýar we
"A"
çap edilýär. - Şol bir global nobatda
print("B")
ýerine ýetirmek üçin sinhron jaň edilýär, bu iş gutarýança häzirki işçi sapagyny ýapýar. - Bu ýagdaýda, ýüplük petiklenen hem bolsa, global nobat birmeňzeş bolansoň, indiki amaly ýerine ýetirip, häzirki işiniň gutarmagyna garaşman, başga bir sapakda işledip biler. Şeýlelik bilen, çagyryş sapagy
print("B")
işiniň başga bir işçi sapagynda ýerine ýetirilmegine garaşýar. - Wezipe gutaransoň, başlangyç jaň sapagy açylýar,
"C"
çap edilýär.
Jogap : ABC
6-njy wezipe
print("A") DispatchQueue.main.async { // 1 print("B") DispatchQueue.main.async { // 2 print("C") DispatchQueue.main.async { // 3 print("D") DispatchQueue.main.sync { print("E") } } // 4 } // 5 DispatchQueue.global().sync { // 6 print("F") DispatchQueue.global().sync { print("G") } } // 7 print("H") } // 8 print("I")
Esasy sapak
"A"
çap edýär.Asynkron däl mesele (1–8 ädimler) häzirki sapagy petiklemän esasy nobata ýazylýar.
Esasy sapak dowam edýär we
"I"
çap edilýär.Soň bolsa, esasy sapak mugt bolanda, esasy nobata berlen ýerine ýetiriş başlaýar we
"B"
çap edilýär.Başga bir asynkron mesele (2-5 ädim) esasy nobata ýazylýar - häzirki sapagy petiklemeýär.
Häzirki sapakda ýerine ýetirilmegini dowam etdirmek bilen, 6–7 amaly sinhron iberiş global nobata iberilýär - bu iş gutarýança häzirki (esasy) sapagy bloklaýar.
6-7-nji amal,
"F"
çap edip, başga bir sapakda ýerine ýetirilip başlaýar.print("G")
amaly, häzirki işçi sapagyny gutarýança blokirläp, global nobata sinhron iberilýär."G"
çap edilýär we bu amalyň iberilen işçi sapagy açylýar.6-7-nji amal tamamlanýar, iberilen sapagy (esasy sapak) açýar we
"H"
çap edilýär.1–2 amal gutarandan soň, ýerine ýetiriş esasy nobatda indiki işe - 2–5 operasiýasyna geçýär we
"C"
başlaýar we çap edilýär.3–4-nji amal, sapagy ýapmazdan esasy nobata ýazylýar.
Häzirki amal (2–5) gutaransoň, ýerine ýetiriş indiki amalda (3–4) başlaýar we
"D"
çap edilýär.print("G")
amaly, häzirki sapagy petikläp, esasy nobata sinhron iberilýär.Soňra ulgam esasy sapagyň ýerine ýetirilmegi üçin
print("E")
edilmegine belli bir wagt garaşýar, sebäbi sapak petiklenensoň, bu petiklenýär.
Jogap : AIBFGHCD, petik
Aralyk maşklar
Aralyk kynçylygyň wezipeleri näbelliligi öz içine alýar. Şeýle meseleler seýrek bolsa-da, söhbetdeşliklerde duş gelýär.
7-nji wezipe
DispatchQueue.global().async { print("A") } DispatchQueue.global().async { print("B") }
-
print("A")
häzirki sapagy petiklemän, global nobatda asynkron görnüşde ýazylýar. - Ulgamyň global nobatda wezipe üçin çeşmeler paýlamagyna garaşýarys. Teoriýa boýunça, bu islendik pursatda, hatda
print("B")
. Bu aýratyn ýagdaýda indiki nobat ilki nobata goşulýar we diňe şondan soň global nobata bölünip berilýär. Bu, esasy sapak iň köp çeşme bölünip berlenligi sebäpli bolup geçýär we esasy sapakdaky indiki amal gaty ýeňil (diňe bir mesele goşmak bilen) we iş ýüzünde global nobatda çeşme paýlanyşyndan has çalt ýüze çykýar. Munuň tersini indiki bölümde ara alyp maslahatlaşarys. -
print("B")
global nobata ýazylýar. - Bu aralykda, global nobat çeşme paýlanyşyna garaşýan mahaly esasy sapak dowam edýär.
- Çeşmeler elýeterli bolanda, iki mesele hem ýerine ýetirilýär.
"A"
meseläni çap etmek"B"
-den has ir başlasa-da, buýrugy kepillendirip bilmeris, sebäbi çap etmek atom operasiýasy däl (konsolda çykýan pursat amalyň ahyrynda).
Jogap : (AB)
Gaplaň, harplaryň islendik tertipde peýda bolup biljekdigini görkezýär: AB ýa-da BA.
8-nji wezipe
print("A") DispatchQueue.main.async { print("B") } DispatchQueue.global().async { print("C") }
Bu ýerde diňe "A" -yň ilki çap edilendigine göz ýetirip bileris. Esasy nobatdaky ýa-da global nobatdaky meseläniň has çalt ýerine ýetiriljekdigini takyk kesgitläp bilmeris.
Jogap : A (BC)
9-njy wezipe
DispatchQueue.global(qos: .userInteractive).async { print(“A”) } DispatchQueue.main.async { // 1 print(“B”) }
we
DispatchQueue.global(qos: .userInteractive).async { print(“A”) } print(“B”) // 1
Bir tarapdan, iki ýagdaýda-da esasy sapakda print("B")
ýerine ýetirilýär. Mundan başga-da, global nobatyň haçan bölünip beriljekdigini takyk kesgitläp bilmeris, şonuň üçin teoretiki taýdan "A"
esasy sapakda // 1 bellenen nokada ýetmänkä çap edilip bilner. Emma iş ýüzünde birinji wezipe hemişe AB görnüşinde, ikinjisi BA görnüşinde çap edilýär. Sebäbi birinji ýagdaýda print("B")
iň bolmanda esasy sapagyň indiki RunLoop gaýtalanyşynda ýerine ýetirilýär (ýa-da birnäçe gezek gaýtalanýar), ikinji ýagdaýda print("B")
esasy sapakdaky häzirki RunLoop iterasiýasynda işlemeli. Şeýle-de bolsa, buýrugy kepillendirip bilmeris.
Iki meselä-de jogap : (AB)
10-njy wezipe
print("A") DispatchQueue.global().async { print("B") DispatchQueue.global().async { print("C") } print("D") }
Çykyşyň başlangyjynyň "AB"
bolandygy düşnüklidir. Çap edilenden soň print("C")
, çeşmeleriň haçan bölünjekdigini takyk kesgitläp bilmeris - bu mesele print("D")
. Bu käwagt iş ýüzünde-de bolýar.
Jogap : AB (CD)
11-nji wezipe
let serialQueue = DispatchQueue(label: “com.kirylfamin.serial”, qos: .userInteractive) DispatchQueue.main.async { print(“A”) serialQueue.async { print(“B”) } print(“C”) }
Againene-de, ýörite nobatda çap etmek üçin ("B") çeşmeleriň haçan bölünjekdigini takyk kesgitläp bilmeris. Iş ýüzünde, esasy sapaga iň ýokary ähmiýet berilýändigi sebäpli, "C" adatça "B" -den öň çap edilýär, ýöne bu kepillendirilmeýär.
Jogap : A (BC)
12-nji wezipe
DispatchQueue.global().async { print("A") } print("B") sleep(1) print("C")
Bu ýerde çykyşyň BAC boljakdygy äşgärdir, sebäbi bir sekuntlyk uky global nobatyň çeşmeler paýlamak üçin ýeterlik wagtyny üpjün edýär. Esasy sapak uky bilen petiklenýän bolsa (önümçilikde etmeli däl), başga bir sapakda print("A")
.
Jogap : BAC
13-nji wezipe
DispatchQueue.main.async { print("A") } print("B") sleep(1) print("C")
Bu ýagdaýda print("A")
esasy nobata ýazylanlygy sebäpli, diňe esasy sapakda ýerine ýetirilip bilner. Şeýle-de bolsa, esasy sapak kody ýerine ýetirmegi dowam etdirýär - "B"
çap etmek, soň uklamak, soňra "C"
çap etmek. Diňe şondan soň “RunLoop” berlen işi ýerine ýetirip biler.
Jogap : BCA
Ösen meseleler
Söhbetdeşliklerde bu kynçylyklara duş gelmek ähtimallygyňyz ýok, ýöne olara düşünmek GCD-ni has gowy düşünmäge kömek eder.
Bu ýerdäki “Counter” synpy diňe salgylanma semantikasy üçin ulanylýar:
final class Counter { var count = 0 }
14-nji wezipe
let counter = Counter() DispatchQueue.global().async { DispatchQueue.main.async { print(counter.count) } for _ in (0..<100) { // 1 counter.count += 1 } }
Bu ýerde esasy sapagyň näderejede meşguldygyna baglylykda 0 bilen 100 aralygyndaky islendik san çap edilip bilner. Bilşimiz ýaly, asynkron meseläniň haçan çeşme aljakdygyny takyk çaklap bilmeris - bu işçiniň sapagyndan öň, wagtynda ýa-da soň bolup biler.
Jogap : 0-100
15-nji wezipe
DispatchQueue.global(qos: .userInitiated).async { print(“A”) } DispatchQueue.global(qos: .userInteractive).async { print(“B”) }
QoS, has ileri tutulýan nobatyň has çalt çeşme aljakdygyny kepillendirmeýär, emma iOS muny etmäge synanyşar. Iş ýüzünde bu ýerdäki çykyş (AB).
Jogap : (AB)
16-njy wezipe
var count = 0 DispatchQueue.global(qos: . userInitiated).async { for _ in 0..<1000 { count += 1 } print(“A”) } DispatchQueue.global(qos: .userInteractive).async { for _ in 0..<1000 { count += 1 } print(“B”) }
Ilki haýsy ýerine ýetirişiň başlanýandygyny bilip bilmeýändigimiz sebäpli, hatda 1000 amalda-da haýsy meseläniň has çalt tamamlanjakdygyny kesgitläp bilmeris.
Jogap : (AB)
16.2-nji wezipe
Amallaryň bir wagtda ýerine ýetirip başlamagyny göz öňünde tutýan netije näme?
.UserInteractive nobaty has köp çeşme bölünip berilýändigi sebäpli, 1000 amalyň dowamynda bu nobatyň ýerine ýetirilmegi elmydama has çalt tamamlanar.
Jogap : BA
17-nji wezipe
Şuňa meňzeş çemeleşmäni ulanyp, islendik bölümi öňki bölümdäki näbellilik bilen üýtgedip bileris (mysal üçin, 12-nji wezipe):
let counter = Counter() let serialQueue = DispatchQueue(label: “com.kirylfamin.serial”, qos: .userInteractive) DispatchQueue.main.async { serialQueue.async { print(counter.count) } for _ in 0..<100 { counter.count += 1 } }
0 bilen 100 aralygyndaky islendik san çap edilip bilner. 0-yň çap edilip bilinjekdigi, 12-nji ýumuşda "C"
çykarylyşynyň "B"
öň hemişe bolup biljekdigini kepillendirip bilmeris, aslynda hiç zat üýtgemedi - diňe aýlaw çapdan has az serişde talap edýär (aýlawy ýerine ýetirmekden ozal hem iş ýüzünde doly näbellilige sebäp bolandygyny belläň).
Jogap : 0-100
18-nji wezipe
DispatchQueue.global(qos: .userInitiated).async { print(“A”) } print(“B”) DispatchQueue.global(qos: .userInteractive).async { print(“C”) }
Bu ýerde şuňa meňzeş ýagdaý ýüze çykýar. Teoriýa boýunça print("A")
print("B")
has çalt ýerine ýetirip biler (eger print("B")
birneme agyrrak zat bilen çalşsaňyz). Iş ýüzünde "B"
hemişe ilki çap edilýär. Şeýle-de bolsa, print("B")
print("C")
ýerine ýetirilýändigimiz, "A"
"C"
-den öň çap edilmek ähtimallygyny ep-esli ýokarlandyrýar, sebäbi esasy sapakda print("B")
sarp edilýän goşmaça wagt köplenç .userInitiated nobata çeşme almak we print("A")
üçin ýeterlikdir. Muňa garamazdan, bu kepillendirilmeýär we käwagt "C"
has çalt çap edilip bilner. Şeýlelik bilen, teoriýada doly näbellilik bar; iş ýüzünde B (CA) bolýar.
Jogap : (BCA)
19-njy wezipe
DispatchQueue.global().sync { print(Thread.current) }
Sinhronlamak üçin resminamalar :
"Netijeli optimizasiýa hökmünde bu funksiýa mümkin boldugyça häzirki sapakdaky bloklary ýerine ýetirýär, bir kadadan çykma: esasy iberiş nobatyna iberilen bloklar hemişe esasy sapakda işleýär."
Diýmek, optimizasiýa maksady bilen sinhron jaňlar çagyrylan şol bir sapakda ýerine ýetirilip bilner ( main.sync
-dan başga - ony ulanýan meseleler hemişe esasy sapakda ýerine ýetirilýär). Şeýlelikde, häzirki (esasy) sapak çap edilýär.
Jogap : esasy sapak
20-nji wezipe
DispatchQueue.global().sync { // 1 print(“A”) DispatchQueue.main.sync { print(“B”) } print(“C”) }
Diňe "A"
çap edilýär, sebäbi petik ýüze çykýar. Optimizasiýa sebäpli mesele (1 bellikli) esasy sapakda ýerine ýetirilip başlaýar we soňra main.sync
jaň etmek petiklige sebäp bolýar.
Jogap : А, petik
21-nji wezipe
DispatchQueue.main.async { print("A") DispatchQueue.global().sync { print("B") } print("C") }
Optimizasiýa print("B")
meselesiniň däl-de, häzirki ýerine ýetiriş sapagyna "bölünmegine" sebäp bolýar. Şeýlelikde, kod:
DispatchQueue.global().sync { print("B") }
bilen deňleşýär:
print(“B”)
Jogap : ABC
Bu meselelerden, esasy.sync-y gaty ünsli ulanmalydygyňyz aýdyň, diňe jaňyň esasy sapakdan edilmeýändigine göz ýetireniňizde.
Netije
Bu makalada, iOS-da köp okalmagyň esasy düşünjelerine - sapaklara, meselelere we nobatlara we olaryň özara baglanyşyklaryna ünsi jemledik. GCD-iň esasy, global we adaty nobatlar boýunça meseleleriň ýerine ýetirilişini nädip dolandyrýandygyny öwrendik we yzygiderli we yzygiderli ýerine ýetirişiň arasyndaky tapawutlary ara alyp maslahatlaşdyk. Mundan başga-da, sinhron (sinhron) we asynkron (asynk) mesele iberişiniň arasyndaky möhüm tapawutlary gözden geçirdik, bu çemeleşmeleriň kod ýerine ýetiriş tertibine we wagtyna nähili täsir edýändigini görkezdik. Bu esasy düşünjeleri özleşdirmek, täsirli, durnukly goşundylary gurmak we petik ýaly umumy duzaklardan gaça durmak üçin zerurdyr.
Bu makalada peýdaly bir zat taparsyňyz diýip umyt edýärin. Bir zat düşnüksiz bolsa, Telegram: @kfamyn hakda mugt düşündiriş almak üçin maňa ýüz tutuň.
Degişli baglanyşyklar
- Animhli animasiýalar bilen YouTube kanaly - https://www.youtube.com/@kirylfamin
- Maşklaryň doly kody - https://github.com/kfamyn/GCD-Tasks
- Meniň telegramma - http://t.me/kfamyn
- RunLoop - https://developer.apple.com/documentation/foundation/runloop
-
sync
usuly resminamalary - https://developer.apple.com/documentation/dispatch/dispatchqueue/sync(execute:)-3segw