10

So che è possibile risolvere i problemi di lettore-scrittore in GCD usando le barriere. Dato che io (in genere) cerco di utilizzare NSOperationQueue anziché GCD quando le prestazioni non sono un problema chiave, mi piacerebbe una soluzione compatibile con NSOperation per questo problema.Risolvi i problemi di lettura/scrittura con NSOperationQueue?

Ho provato a scrivere il mio, ma la mia soluzione è diventata ingombrante ... sicuramente qualcuno ha già affrontato questo problema?

Qualcuno sa di una soluzione compatibile con NSOperation per il problema lettore-scrittore?

+0

Bella domanda. Interessato ad alcune soluzioni ... –

+0

Cosa c'è che non va nei semafori? – MattD

+2

L'utilizzo di una barriera GCD sulla base della coda di operazioni, queue dispatch_queue, è un imbroglio? – stevesliva

risposta

1

Come con la maggior NSOperationQueue aggiustamenti, è possibile sfruttare il suo sostegno per le dipendenze tra le operazioni:

  • Creare un NSBlockOperation sottoclasse, ReaderWriterBlockOperation. Aggiunga ad esso la proprietà BOOL writer.
  • Creare una coda di operazioni per risorsa protetta.
  • Interrompe l'esposizione della coda di operazioni ai client. Esporre invece l'API -readWithBlock: e -writeWithBlock:. Entrambi accodano uno ReaderWriterBlockOperation, quello con writer == NO, l'altro == YES. Il loro funzionamento gestisce le dipendenze come segue:
    • -readWithBlock: fa, in un blocco @synchronized(self), una scansione delle operazioni dall'ultimo al primo alla ricerca di un blocco di writer. Se nessuno viene trovato, aggiunge operazione e restituisce. Se ne viene trovato uno, rende il nuovo blocco del lettore dipendente dallo scrittore, lo accoda e ritorna.
    • -writeWithBlock: fa la stessa cosa. Tranne se nessun scrittore viene trovato nelle operazioni in coda, rende il blocco dipendente da tutti i lettori trovati. Se uno viene trovato nelle operazioni in coda, si rende dipendente da tale operazione e da tutte le seguenti operazioni (lettore).

Questo dovrebbe avere il risultato di bloccare tutti i lettori fino alla scrittrice prima di loro ha completato, e bloccando tutti gli scrittori fino i lettori prima di loro hanno completato.

Un possibile problema: non sono chiaro (perché i documenti non sono chiari, e non l'ho ancora implementato come tale) se NSBlockOperation in realtà attende il completamento del blocco prima di dichiararsi completo. In caso contrario, dovrai gestirlo da solo nella sottoclasse delle operazioni.

Tutto ciò detto, se il sistema fornisce una soluzione di lavoro, come blocchi di barriera, è necessario utilizzarlo. L'intero sistema è un hack per ottenere una coda di operazioni per fare qualcosa che le code di distribuzione sono state regolate per gestire molto bene. Se le prestazioni non sono in realtà un problema, perché non utilizzare solo una coda seriale (NSOperationQueue con il numero massimo di operazioni simultanee == 1)?