Grand Central Dispatch

Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den version , der blev gennemgået den 20. februar 2016; checks kræver 11 redigeringer .

Grand Central Dispatch ( GCD ) er Apples teknologi til at bygge applikationer, der udnytter multi-core processorer og andre SMP - systemer [1] . Denne teknologi er en implementering af opgaveparallelisme og er baseret på Thread Pool -designmønsteret . GCD blev først introduceret med Mac OS X 10.6 . Kildekoden til libdispatch- biblioteket , som implementerer GCD-tjenesterne, blev frigivet under Apache-licensen den 10. september  2009. [ 1] Arkiveret den 2. november 2009 på Wayback Machine . Efterfølgende blev biblioteket porteret [2] til et andet FreeBSD -operativsystem [3] .

GCD giver dig mulighed for at definere opgaver i en applikation, der kan udføres parallelt, og kører dem, når der er ledige computerressourcer ( processorkerner ) [4] .

En opgave kan defineres som en funktion eller som en " blok ". [5] En blok er en ikke-standard syntaksudvidelse af C / C ++ / Objective-C programmeringssprogene, der indkapsler kode og data i et enkelt objekt, analogt med en lukning . [fire]

Grand Central Dispatch bruger tråde på et lavt niveau, men skjuler implementeringsdetaljer fra programmøren. GCD-opgaver er lette, billige at oprette og skifte; Apple hævder, at tilføjelse af en opgave til køen kun kræver 15 processorinstruktioner , mens oprettelse af en traditionel tråd koster flere hundrede instruktioner. [fire]

En GCD-opgave kan bruges til at oprette et arbejdsemne, der er placeret i en opgavekø eller kan være bundet til en hændelseskilde. I det andet tilfælde, når hændelsen udløses, føjes opgaven til den relevante kø. Apple hævder, at denne mulighed er mere effektiv end at oprette en separat tråd, der venter på, at begivenheden udløses.

Platformfunktioner

GCD-rammen erklærer flere datatyper og funktioner til at skabe og manipulere dem.

Eksempler

To eksempler, der demonstrerer brugervenligheden af ​​Grand Central Dispatch, kan findes i John Syracuse's Snow Leopard anmeldelse på Ars Technica . [6] .

Asynkront opkald

I første omgang har vi en applikation med analyseDokumentmetode, der tæller ord og afsnit i et dokument. Normalt er processen med at tælle ord og afsnit hurtigt nok og kan udføres på hovedtråden uden frygt for, at brugeren vil bemærke en forsinkelse mellem at trykke på knappen og få resultatet:

- ( IBAction ) analyseDokument: ( NSButton * ) sender { NSDictionary * stats = [ myDoc analyse ]; [ myModel setDict : statistik ]; [ myStatsView setNeedsDisplay : YES ]; }

Hvis dokumentet er meget stort, så kan analysen tage ret lang tid for brugeren at bemærke, at applikationen "hænger". Følgende eksempel gør det nemt at løse dette problem:

- ( IBAction ) analyseDocument :( NSButton * ) sender { dispatch_async ( dispatch_get_global_queue ( 0 , 0 ), ^ { NSDictionary * stats = [ myDoc analyse ]; dispatch_async ( dispatch_get_main_queue (), ^ { [ myModel setDict : statistik ]; [ myStatsView setNeedsDisplay : YES ]; }); }); }

Her placeres [myDoc analyse]-kaldet i en blok, som derefter placeres i en af ​​de globale køer. Efter at [myDoc analyse] er fuldført, placeres en ny blok på hovedkøen, som opdaterer brugergrænsefladen . Ved at foretage disse enkle ændringer undgik programmøren det potentielle hængende i applikationen ved parsing af store dokumenter.

Løkkeparallelisering

Det andet eksempel viser paralleliseringen af ​​løkken:

for ( i = 0 ; i < tælle ; i ++ ) { resultater [ i ] = udføre_arbejde ( data , i ); } total = opsummere ( resultater , tælle );

Her kaldes do_work-funktionen tælletider , resultatet af dens i-te udførelse tildeles det i-te element i resultatarrayet, hvorefter resultaterne summeres. Der er ingen grund til at tro, at do_works er afhængig af resultaterne af tidligere opkald til det, så der er intet til at stoppe med at udføre flere opkald til do_works parallelt. Følgende liste viser implementeringen af ​​denne idé ved hjælp af GCD:

dispatch_apply ( count , dispatch_get_global_queue ( 0 , 0 ), ^ ( size_t i ){ resultater [ i ] = udføre_arbejde ( data , i ); }); total = opsummere ( resultater , tælle );

I dette eksempel kører dispatch_apply tæller gange blokken blev overført til den, placerer hvert opkald i den globale kø og sender bloknumrene fra 0 til count-1. Dette gør det muligt for OS at vælge det optimale antal tråde for at få mest muligt ud af de tilgængelige hardwareressourcer. dispatch_apply vender ikke tilbage, før alle dens blokke er afsluttet, for at sikre, at alt det originale loops arbejde er afsluttet, før summary kaldes.

Oprettelse af sekventielle køer

Udvikleren kan oprette en separat seriel kø for opgaver, der skal køre sekventielt, men kan køre på en separat tråd. En ny kø kan oprettes på denne måde:

dispatch_queue_t exampleQueue ; exampleQueue = dispatch_queue_create ( "com.example.unique.identifier" , NULL ); // exampleQueue kan bruges her. dispatch_release ( eksempelkø );

Undgå at sætte en sådan opgave i en sekventiel kø, der sætter en anden opgave i samme kø. Dette vil med garanti resultere i en dødvande . Følgende liste viser et tilfælde af en sådan dødvande:

dispatch_queue_t exampleQueue = dispatch_queue_create ( "com.example.unique.identifier" , NULL ); dispatch_sync ( eksempelkø , ^ { dispatch_sync ( eksempelkø , ^ { printf ( "Jeg er nu fastlåst... \n " ); }); }); dispatch_release ( eksempelkø );

Se også

Links

  1. Apple forhåndsviser Mac OS X Snow Leopard til udviklere Arkiveret 11. juni 2008. .
  2. GCD libdispatch w/Blocks understøtter arbejde på FreeBSD . Hentet 31. oktober 2009. Arkiveret fra originalen 27. juli 2011.
  3. FreeBSD kvartalsvise statusrapport . Hentet 31. oktober 2009. Arkiveret fra originalen 14. oktober 2009.
  4. 1 2 3 Apple Technical Brief om Grand Central Dispatch Arkiveret 20. september 2009 på Wayback Machine Arkiveret 20. september 2009. .
  5. Grand Central Dispatch (GCD) Reference (utilgængeligt link) . Hentet 31. oktober 2009. Arkiveret fra originalen 9. april 2012. 
  6. Mac OS X 10.6 Snow Leopard: Ars Technica-anmeldelsen . Hentet 28. september 2017. Arkiveret fra originalen 9. maj 2012.