2012-06-11 9 views
39

Sto scrivendo un programma iOS moderatamente complesso che deve avere più thread per alcune delle operazioni più lunghe (analisi, connessioni alla rete ... ecc.). Tuttavia, sono confuso su quale sia la differenza tra dispatch_get_global_queue e dispatch_queue_create.Qual è la differenza tra dispatch_get_global_queue e dispatch_queue_create?

Quale dovrei usare e potresti darmi una semplice spiegazione di quale sia la differenza in generale? Grazie.

+1

Ya .. u scelto risposta sbagliata. La risposta di Robert Ryan è più appropriata –

risposta

68

Come descrive lo documentation, una coda globale è utile per attività concorrenti (ad esempio, si invierà varie attività in modo asincrono e si è perfettamente felici se vengono eseguite contemporaneamente) e se non si desidera incontrare la teoria sovraccarico di creare e distruggere la propria coda.

La creazione della propria coda è molto utile se è necessaria una coda seriale (vale a dire che i blocchi inviati devono essere eseguiti uno alla volta). Questo può essere utile in molti scenari, ad esempio quando ogni attività dipende da quella precedente o quando si coordinano le interazioni con alcune risorse condivise da più thread.

Meno comune, ma è anche necessario creare la propria coda se è necessario utilizzare barriers in concomitanza con una coda concorrente. In tale scenario, creare una coda concorrente (ad esempio dispatch_queue_create con l'opzione DISPATCH_QUEUE_CONCURRENT) e utilizzare le barriere in concomitanza con quella coda. Non dovresti mai usare barriere sulle code globali.

Il mio consiglio generale è se hai bisogno di una coda seriale (o devi usare le barriere), quindi crea una coda. In caso contrario, andare avanti e utilizzare la coda globale e ignorare il sovraccarico di creare il proprio.


Se si desidera una coda concorrente, ma si desidera controllare il numero di operazioni possono essere eseguite contemporaneamente, si può anche considerare l'utilizzo di NSOperationQueue che ha una proprietà maxConcurrentOperationCount. Ciò può essere utile quando si eseguono operazioni di rete e non si desidera che vengano inviate troppe richieste simultanee al server.

+2

Si noti che in Lion è ora possibile ottenere una coda concorrente da 'dispatch_queue_create()' passando 'DISPATCH_QUEUE_CONCURRENT'. Non è specificato (e probabilmente non importa) se questo restituirà solo una delle code globali esistenti. –

+1

Avrei dovuto aggiungere, "presumibilmente che la funzionalità arriverà su iOS alla fine". –

+1

Suvviato per aver correttamente evidenziato le differenze in termini di code simultanee e seriali. – user523234

0

Uno restituisce la coda globale esistente, l'altra ne crea una nuova. Invece di usare GCD, prenderei in considerazione l'utilizzo di NSOperation e la coda di operazioni. È possibile trovare ulteriori informazioni a riguardo in this guide. In genere, si desidera che le operazioni vengano eseguite contemporaneamente, si desidera creare la propria coda e inserire le operazioni in essa.

+0

Giusto per chiarire, se si sta creando una coda di invio, è seriale. Se stai utilizzando la coda di invio globale, può essere simultanea (ma non è garantito che sia così). Presumo che il tuo consiglio nella creazione di code per la concorrenza sia correlato alle code di operazioni, non alle code di invio. (So ​​che lo sai, ma volevo solo assicurarmi che i lettori non fossero confusi.) – Rob

+1

Sì, sto parlando di code di operazioni. Un po 'di tempo fa mi trovavo di fronte allo stesso problema e, quando ho creato la mia coda di operazioni senza ulteriori configurazioni, le operazioni aggiunte venivano eseguite simultaneamente l'una con l'altra. –

40

appena pubblicato in una risposta diversa, ma qui è qualcosa che ho scritto un bel po 'indietro:

Il modo migliore per concettualizzare le code è rendersi conto prima che al livello molto basso, ci sono solo due tipi di code: seriale e concomitante.

Code seriali sono monogame, ma senza impegno. Se assegni un sacco di compiti a ciascuna coda seriale, li eseguirà uno alla volta, usando solo un thread alla volta. L'aspetto non vincolato è che le code seriali possono passare a un thread diverso tra le attività. Le code seriali attendono sempre che un'operazione finisca prima di passare a quella successiva. Quindi le attività sono completate in ordine FIFO. È possibile creare tutte le code seriali necessarie con dispatch_queue_create.

La coda è una coda seriale speciale. A differenza di altre code seriali, che non sono condivise, in quanto "datano" molti thread ma solo uno alla volta, la coda principale è "sposata" al thread principale e tutte le attività vengono eseguite su di esso.I lavori sulla coda principale devono comportarsi bene con il runloop in modo che le piccole operazioni non blocchino l'interfaccia utente e altri bit importanti. Come tutte le code seriali, le attività sono completate in ordine FIFO.

Se le code seriali sono monogame, le code simultanee sono promiscue. Essi invieranno compiti a qualsiasi thread disponibile o potranno persino creare nuovi thread in base al carico del sistema. Possono eseguire più attività contemporaneamente su thread diversi. È importante che le attività inviate alla coda globale siano thread-safe e riducano al minimo gli effetti collaterali. Le attività vengono inviate per l'esecuzione in ordine FIFO, ma l'ordine di completamento non è garantito. Al momento della stesura di questo documento, esistono solo tre code simultanee e non è possibile crearle, è possibile recuperarle solo con dispatch_get_global_queue.

edit: post sul blog in espansione su questa risposta: http://amattn.com/p/grand_central_dispatch_gcd_summary_syntax_best_practices.html

+2

Il migliore. Risposta. Mai. –

+1

Il link del post del blog è morto. –

+0

Sembra ancora funzionare per me. Di recente ho aggiornato i motori dei blog, quindi qui è disponibile un nuovo indirizzo canonico: http://amattn.com/p/grand_central_dispatch_gcd_summary_syntax_best_practices.html – amattn

Problemi correlati