2011-01-09 13 views
12

Sto costruendo una libreria di giochi in C++. Un po 'di tempo fa stavo usando Qt per costruire un'applicazione ed ero piuttosto affascinato dal suo uso di Implicit Sharing. Mi chiedo se qualcuno possa spiegare questa tecnica in modo più dettagliato o potrebbe offrire un semplice esempio di questo in azione.Che cos'è la condivisione implicita?

+5

hai dato un link per i documenti che forniscono una eccellente spiegazione di come funziona. Ha anche un riferimento a [i documenti dei thread che spiegano come il conteggio dei riferimenti atomici aiuta nelle app multi-thread] (http://doc.trolltech.com/latest/threads-modules.html#threads-and-implicitly-shared-classes). Se qualcosa non è ancora chiaro, dovresti fare una domanda più dettagliata su quel qualcosa. E non dimenticare che puoi sempre guardare le fonti di Qt. –

+0

L'altro nome per * sharing implicito * è * copy-on-write *. Potresti dare un'occhiata alle domande che citano questo altro nome su SO come per esempio questo: http://stackoverflow.com/questions/628938/what-is-copy-on-write –

+0

Credo che la condivisione implicita sia solo di Qt implementazione di [copy-on-write] (https://en.wikipedia.org/wiki/Copy-on-write). – HelloGoodbye

risposta

31

L'idea chiave dietro la condivisione implicita sembra andare in giro usando il termine più comune copy-on-write. L'idea alla base del copy-on-write è di far sì che ciascun oggetto funga da wrapper attorno a un puntatore all'attuazione reale. Ogni oggetto di implementazione tiene traccia del numero di puntatori in esso contenuti. Ogni volta che un'operazione viene eseguita sull'oggetto wrapper, viene semplicemente inoltrata all'oggetto di implementazione, che esegue il lavoro effettivo.

Il vantaggio di questo approccio è che la copia e la distruzione di questi oggetti sono a buon mercato. Per effettuare una copia dell'oggetto, facciamo appena una nuova istanza di un involucro, impostare il puntatore per puntare l'oggetto attuazione, e quindi incrementare il conteggio del numero di puntatori all'oggetto (questo è talvolta chiamato il conteggio riferimento, a proposito). La distruzione è simile: rilasciamo il conteggio di riferimento di uno, quindi vediamo se qualcun altro sta indicando l'implementazione. Altrimenti, liberiamo le sue risorse. Altrimenti, non facciamo nulla e assumiamo che qualcun altro eseguirà la pulizia in un secondo momento.

La sfida in questo approccio è che significa che più oggetti diversi saranno tutti puntano alla stessa attuazione. Ciò significa che se qualcuno finisce per apportare una modifica all'implementazione, ogni oggetto che fa riferimento a tale implementazione vedrà le modifiche, un problema molto serio. Per risolvere questo problema, ogni volta che viene eseguita un'operazione che potrebbe potenzialmente modificare l'implementazione, l'operazione verifica se anche altri oggetti fanno riferimento all'implementazione vedendo se il conteggio dei riferimenti è identico 1. Se nessun altro oggetto fa riferimento all'oggetto, allora il l'operazione può solo andare avanti - non c'è possibilità che le modifiche si propagino. Se esiste almeno un altro oggetto che fa riferimento ai dati, il wrapper esegue innanzitutto una copia profonda dell'implementazione per se stesso e modifica il puntatore in modo che punti al nuovo oggetto. Ora sappiamo che non può esserci condivisione, e le modifiche possono essere apportate senza problemi.

Se desideri vedere alcuni esempi di questo in azione, dai un'occhiata agli esempi di lezione 15.0 e 16.0 da Stanford's introductory C++ programming course. Mostra come progettare un oggetto per contenere un elenco di parole usando questa tecnica.

Spero che questo aiuti!