2013-10-04 16 views
6

So che potresti trovare questa domanda strana, ma sto solo imparando GCD e voglio comprendere appieno tutti i suoi aspetti. Quindi eccolo:Invio sincronizzazione sulla coda corrente

C'è qualche motivo per inviare un'attività SYNC sulla CODA CORRENTE?

Ad esempio:

dispatch_queue_t concurrentQueue = dispatch_get_global_queue(...); 
    dispatch_async(concurrentQueue, ^{ 
     //this is work task 0 

     //first do something here, then suddenly: 

     dispatch_sync(concurrentQueue, ^{ 
       //work task 1 
     }); 

     //continue work task 0 
    }); 

ho capito una cosa: se invece di concurrentQueue io uso una coda serie, allora ottengo una situazione di stallo su quella coda di serie, perché work task 1 non può iniziare fino a quando il work task 0 è finito (a causa della coda seriale che garantisce l'ordine di esecuzione), e nello stesso tempo work task 0 non può continuare la sua esecuzione perché attende la funzione di dispath SYNC per tornare (correggi se ho torto, questo mi farebbe un totale noob).

Quindi tornando all'idea originale, v'è alcuna differenza di sorta tra il codice di cui sopra e lo stesso codice in cui, invece di chiamare la funzione dispatch_sync ho semplicemente scrivere work task 1 codice direttamente?

risposta

7

No. Non riesco a pensare a una ragione per sempre dispatch_sync sulla stessa coda concorrente in cui ci si trova già. Se lo fai, GCD invocherà immediatamente il tuo blocco, in linea, sullo stesso thread, come se lo avessi chiamato direttamente. (Ho controllato.) E come hai fatto notare, farlo in una coda seriale ti bloccherà.

+0

Mi sto prendendo alla sprovvista, ma che ne dici se vuoi che una particolare attività si verifichi su una certa coda, ma l'attività di emissione può o non può avvenire in quella coda? L'unico problema allora è venire con uno scenario realistico in cui la coda è concomitante. – Tommy

+0

@Tommy la domanda era: è dispatch_sync per la stessa coda superfluo ?. La tua domanda sembra essere, c'è un punto per dispatch_sync su una coda concorrente che è potenzialmente diversa da quella corrente ?. Sì, se vuoi che la tua prossima riga di codice avvenga dopo il codice di dispatch_sync. Uno scenario realistico sarebbe: una complessa gerarchia di code e/o codice che retarget le code (perché il blocco può finire ovunque). – Jano

+0

@Jano Non hai capito il mio commento. È correlato alla risposta di ipmcc, quindi sto rispondendo a "Non riesco a pensare a un motivo per dispatch_sync sulla stessa coda concorrente in cui sei già", non alla domanda originale. Una ragione potrebbe essere: si vuole sicuramente un compito fatto su quella coda. Non sai se ci sei già. Sì, potresti scrivere il codice per verificarlo, ma dovresti semplicemente duplicare il codice che Apple ha già scritto, quindi c'è un buon argomento per non farlo. – Tommy

3

assuma questa coda per tutti gli esempi:

dispatch_queue_t coda = dispatch_queue_create (“com.somecompany.queue”, pari a zero);

Situazione 1 - OK

dispatch_async(queue, ^{ 
    [self goDoSomethingLongAndInvolved]; 
    dispatch_async(queue, ^{ 
     NSLog(@"Situation 1"); 
    }); 
}); 

Situazione 2 - Non OK! Deadlock!

dispatch_sync(queue, ^{ 
    [self goDoSomethingLongAndInvolved]; 
    dispatch_sync(queue, ^{ 
     NSLog(@"Situation 2”); // NOT REACHED! DEADLOCK! 
    }); 
}); 

Situazione 3 - Non OK! Deadlock!

dispatch_async(queue, ^{ 
    [self goDoSomethingLongAndInvolved]; 
    dispatch_sync(queue, ^{ 
     NSLog(@"Situation 3"); // NOT REACHED! DEADLOCK! 
    }); 
}); 

Situazione 4 - OK

dispatch_sync(queue, ^{ 
    [self goDoSomethingLongAndInvolved]; 
    dispatch_async(queue, ^{ 
     NSLog(@"Situation 4"); 
    }); 
}); 

Fondamentalmente dispatch_sync non piace essere al suo interno.

Solo dispatch_asyncs può entrare.

Problemi correlati