Paralelismul în mediile Cocoa, Mac OS, iOS
Posturi de expediere.
Mesajele de expediere de tip Central Central Dispatch (GCD) reprezintă un instrument puternic pentru efectuarea sarcinilor. Trimiterea unei coadă vă permite să executați blocuri libere arbitrare, fie asincron, fie sincron cu firul de apel. Puteți utiliza coada de expediere pentru a efectua aproape toate sarcinile care sunt utilizate pentru a rula pe fire individuale. Avantajul cozi de trimitere este că acestea sunt mai ușor de utilizat și mult mai eficiente în realizarea acestor sarcini decât codul multithreaded corespunzător.
Trimiterea unei coadă este o structură asemănătoare obiectului care gestionează sarcinile care o reprezintă. Toate cozile trimise sunt integrate în structura de date în conformitate cu principiul: pentru prima dată introdus, primul afară. Astfel, sarcinile adăugate la coadă intră întotdeauna în aceeași ordine în care au fost adăugate. GCD oferă câteva cozi de trimitere pentru dvs. în mod automat, în timp ce altele pot crea pentru scopuri specifice. Tabelul 3-1 enumeră tipurile de coadă de expediere disponibile pentru aplicația dvs. și o descriere a modului în care le folosiți în continuare.
Tabelul 3-1 Tipuri de trimitere în coadă
coadă secvențială (de asemenea, cunoscut sub numele de cozi private de expediere) efectuează o sarcină la un moment dat, în ordinea în care acestea vor fi adăugate la coadă. Execuția curentă a sarcinii rulează pe fire diferite (care pot varia de la sarcină la sarcină), care sunt controlate prin trimiterea coadă. Cozile secvențiale sunt adesea folosite pentru a sincroniza accesul la o anumită resursă.
Puteți crea cât mai multe cozi consecutive de câte aveți nevoie și fiecare coadă funcționează simultan pentru toate celelalte cozi. Cu alte cuvinte, dacă creați patru coadouri consecutive, fiecare coadă execută numai o singură sarcină la un moment dat, dar până la patru sarcini, ea poate fi executată simultan, una din fiecare coadă. Pentru informații despre cum se creează o coadă de serie, consultați "Crearea unei coada de trimitere consecutivă".
O coadă paralelă (cunoscută și ca tip de coadă de expediere globală) îndeplinește una sau mai multe sarcini în același timp, dar sarcinile sunt încă pornite în ordinea în care au fost adăugate la coadă. Execuția curentă a sarcinii rulează pe diferite fire care sunt gestionate de coada de expediere. Numărul exact al sarcinilor care se execută în acest moment este variabil și depinde de condițiile sistemului.
Nu puteți crea cozi paralele pentru trimitere. În schimb, există trei așteptări globale pentru utilizarea concomitentă în aplicația dvs. Pentru mai multe informații despre cum să obțineți o coadă globală concurentă, consultați "Obținerea unei coloane paralele de trimitere globală".
Principala coadă de expediere
Principala coadă de trimitere este o coadă secvențială disponibilă la nivel global care execută sarcini pe firul principal al aplicației. Toate acestea funcționează cu ciclul principal al cererii (dacă este cazul) la sarcini alternative, în conformitate cu performanța altor surse de evenimente atașate la ciclul principal al aplicației. Deoarece rulează pe firul principal al aplicației, coada principală este adesea folosită ca punct cheie de sincronizare pentru aplicație.
Deși nu este nevoie să creați o coadă principală de trimitere, trebuie să vă asigurați că cererea dvs. continuă în mod corespunzător. Pentru mai multe informații despre modul în care este gestionată această coadă, vedeți "Rularea sarcinilor în firul principal".
Când vine vorba de adăugarea unei concurențe unei aplicații, trimiterea cozilor oferă un număr de avantaje față de fire. Avantajul cel mai direct este facilitatea funcționării modelului de programare a coada de așteptare. Cu fire, trebuie să scrieți cod, atât pentru sarcina pe care trebuie să o îndepliniți, cât și pentru crearea și gestionarea firelor. Trimiterea unei coada vă va permite să vă concentrați asupra sarcinii pe care doriți să o realizați fără a vă îngrijora de crearea și gestionarea firelor. În schimb, sistemul se ocupă de crearea și gestionarea firelor pentru dvs. Avantajul este că sistemul poate gestiona firele mult mai eficient decât orice altă aplicație vreodată. Sistemul poate scala dinamic numărul de fire pe baza resurselor disponibile și a stării actuale a sistemului. În plus, sistemul are, de obicei, o capacitate mai rapidă de a vă executa sarcina decât tine, dacă ați creat singur firul.
În timp ce s-ar putea crede că pentru a rescrie codul pentru a trimite coada va fi dificil, adesea este mai ușor să scrie cod pentru a trimite coadă, scrieți codul pentru fluxul. Cheia este scrierea codului pentru a dezvolta sarcini care sunt autonome și capabile să funcționeze în modul asincron. (De fapt, acest lucru este valabil pentru fire și pentru trimiterea cozilor). Cu toate acestea, avantajul de a trimite o coadă este predictibilitatea. Dacă aveți două sarcini care accesează aceeași resursă partajată, dar operează pe diferite fire, un fir poate schimba resursa în primul rând, și va trebui să utilizeze un sistem de blocare care ambele obiective nu au modificat această resursă în același timp. La trimiterea unei cozi, puteți adăuga o sarcină la o coadă de expediere serial la doar o singură sarcină de a modifica resursele la un moment dat. Acest tip de sincronizare bazată pe coadă este mai eficientă decât de blocare, deoarece blocare necesită întotdeauna un miez capcană costisitoare și contestată în cazuri necontestate, în timp ce coada trimiterea funcționează în principal în procesul de aplicare spațiu și numai provoacă la nivelul nucleului, în cazul în care absolut necesar.
Deși este corect să spunem că două sarcini care rulează într-o coadă secvențială nu pot funcționa simultan, trebuie să rețineți că dacă două fire acceptă o blocare în același timp, orice concurență oferită de firele de execuție este pierdută sau redusă semnificativ. Mai mult decât atât, cu modelul de streaming, este necesar să creați două fire, care ocupă atât spațiul de bază, cât și spațiul de memorie al utilizatorului. Managerul coadă nu plătește prețul pentru alocarea de memorie pentru fluxurile și fluxurile sale, pe care le folosesc reținute ocupat și nu a blocat.
Tehnologii legate de coadă
În plus față de trimiterea coadă, Grand Central Dispatch oferă mai multe tehnologii care utilizează cozi pentru a ajuta la gestionarea codului. Tabelul 3-2 enumeră aceste tehnologii, precum și linkuri unde puteți afla mai multe informații despre ele.
Tabelul 3-2 Tehnologii care utilizează cozi de trimitere