2010-10-21 14 views
13

Ho scritto un codice che sostituisce alcuni esistente:Qual è la differenza tra GCD Dispatch Sources e select()?

while(runEventLoop){ 
    if(select(openSockets, readFDS, writeFDS, errFDS, timeout) > 0){ 
    // check file descriptors for activity and dispatch events based on same 
    } 
} 

presa codice di lettura. Mi piacerebbe cambiarlo per usare una coda GCD, in modo che io possa far apparire gli eventi in coda usando dispatch_async invece di mantenere un array "deve essere chiamato sulla prossima iterazione". Inoltre sto già utilizzando una coda GCD per/contenere/questa particolare azione, quindi voglio delegarla a un modulo di invio GCD più naturale. (Non un ciclo while() monopolizzare una coda di serie)

Tuttavia, quando ho cercato di refactoring questo in una forma che si basava su fonti di invio sparato da gestori di eventi legati alla DISPATCH_SOURCE_TYPE_READ e DISPATCH_SOURCE_TYPE_WRITE sui descrittori di socket, il codice libreria che dipendeva da questa programmazione smesso di funzionare. La mia prima ipotesi è che io stia fraintendendo l'uso di DISPATCH_SOURCE_TYPE_READ e DISPATCH_SOURCE_TYPE_WRITE: ho pensato che avrebbero dato all'incirca lo stesso comportamento di chiamare select() con quei descrittori di socket.

Non capisco male le fonti di spedizione GCD? Oppure, riguardo al refactoring, lo sto usando in una situazione in cui non è più adatto?

+0

Dovresti mostrare il codice: cosa hai provato. Nel frattempo, Mike Ash ha un codice di esempio da verificare - http://www.mikeash.com/svn/GCDWeb/GCDWeb.m - server Web GCD. – robertvojta

risposta

3

La risposta breve alla tua domanda è: nessuna. Non ci sono differenze, entrambe le fonti di invio GCD e select() fanno la stessa cosa: notificano all'utente che è accaduto uno specifico evento del kernel o che una particolare condizione è vera.

Si noti che, su un Mac o un dispositivo iOS non si dovrebbe usare select(), ma piuttosto il più avanzato e kqueue()kevent() (o kevent64()).

Si può certamente convertire il codice per utilizzare le fonti di invio GCD, ma è necessario fare attenzione a non violare altro codice basandosi su questo. Quindi, questo richiede un'ispezione completa di tutti i segnali di gestione del codice, i descrittori di file, il socket e tutti gli altri eventi del kernel di basso livello.

Potrebbe essere una soluzione più semplice potrebbe essere quella di mantenere il codice originale, semplicemente aggiungendo il codice GCD nella parte che reagisce agli eventi. Qui, si inviano eventi su code diverse a seconda del particolare tipo di evento.

+0

Sono d'accordo, una differenza è che con GCD è possibile modulare il codice in macchine a stati separati con code di invio indipendenti associate a ciascuna sorgente. Non sono sicuro, ma immagino che GCD potrebbe utilizzare qualcosa di simile a se stesso. – user210504

+2

Puoi essere più specifico sul perché kqueue() è meglio di select() su iOS? Dalla mia breve esplorazione, sembra che kqueue() sia preferito quando hai molti eventi da monitorare, ma c'è qualche ragione per credere che sia meglio di select() su un fdset con un singolo fd? In tal caso, sembra che la semantica sia quasi identica, quindi non è sicuro del perché le prestazioni sarebbero diverse? – user1055568

+1

Le esibizioni sono in realtà diverse: provalo tu stesso. Dovresti vedere che, anche per un singolo descrittore di file con un'attività intensa, kqueue() funziona meglio. Probabilmente, Apple non ha insistito troppo nel migliorare la vecchia implementazione select(). La nuova chiamata di sistema queue() è molto più potente e offre prestazioni migliori. L'unica ragione per cui vedo usare select() è che hai un codice legacy che non vuoi aggiornare. –

Problemi correlati