2009-12-23 5 views
8

Abbiamo bisogno di più programmi per chiamare le funzioni in una libreria comune. Le funzioni della libreria accedono e aggiornano una memoria globale comune. Le chiamate di funzione di ogni programma devono vedere questa memoria globale comune. Quella è una chiamata di funzione ha bisogno di vedere gli aggiornamenti di qualsiasi chiamata di funzione precedente anche se chiamata da un altro programma. Per ragioni di compatibilità abbiamo diversi vincoli di progettazione su come le funzioni esposte dalla libreria condivisa devono operare:Instantiating degli oggetti nella memoria condivisa C++

  • Eventuali elementi di dati (entrambi i tipi di dati standard e oggetti) che vengono dichiarati a livello globale devono essere visibili a tutti i chiamanti a prescindere il thread in cui è in esecuzione il codice.
  • Tutti gli elementi di dati dichiarati localmente in una funzione sono visibili solo all'interno di tale funzione.
  • Qualsiasi tipo di dati standard o un'istanza di qualsiasi classe possono essere visualizzati localmente o globalmente o entrambi.

Una soluzione consiste nel mettere la memoria globale comune della libreria nella memoria condivisa denominata. La prima chiamata alla libreria creerebbe la memoria condivisa con nome e la inizializzerà. Le chiamate di programma successive otterrebbero l'indirizzo della memoria condivisa e lo userebbero come un puntatore alla struttura globale dei dati. Le istanze dell'oggetto dichiarate globalmente dovrebbero essere allocate dinamicamente nella memoria condivisa mentre le istanze dell'oggetto dichiarate localmente possono essere posizionate nello stack o nell'heap locale del thread del chiamante. I problemi sorgono perché oggetti inizializzati nella memoria globale possono creare e puntare a oggetti secondari che allocano (nuova) memoria aggiuntiva. Queste nuove allocazioni devono anche essere nella memoria condivisa e viste da tutti i chiamanti di libreria. Un'altra complicazione è che questi oggetti, che contengono stringhe, file, ecc., Possono essere utilizzati anche nel programma chiamante. Quando dichiarato nel programma chiamante, la memoria dell'oggetto è locale al programma chiamante, non condivisa. Quindi il codice dell'oggetto deve gestire entrambi i casi. Ci sembra che la soluzione richieda di scavalcare il posizionamento globale nuovi, regolari operatori nuovi ed eliminati. Abbiamo trovato un progetto per un sistema di gestione della memoria che sembra funzionerà, ma non abbiamo trovato alcuna implementazione effettiva. Se qualcuno è a conoscenza dell'implementazione del progetto di gestione della memoria di Nathan Myers (http://www.cantrip.org/wave12.html?seenIEPage=1), gradirei un collegamento ad esso. In alternativa, se qualcuno conosce un altro gestore di memoria condivisa che ospita allocazione dinamica degli oggetti, mi piacerebbe anche saperlo. Ho controllato le librerie Boost e tutte le altre fonti che riesco a trovare, ma nulla sembra fare ciò di cui abbiamo bisogno. Preferiamo non doverne scrivere uno da soli. Dato che le prestazioni e la robustezza sono importanti, sarebbe bello utilizzare un codice comprovato. Grazie in anticipo per qualsiasi idea/aiuto.

Grazie per i suggerimenti sulle librerie ATL e OSSP. Li sto verificando ora, anche se temo che ATL sia troppo Wincentrico se l'obiettivo è Unix.

Un'altra cosa ci sembra chiara. Poiché gli oggetti possono essere creati dinamicamente durante l'esecuzione, lo schema di gestione della memoria deve essere in grado di allocare ulteriori pagine di memoria condivisa. Questo sta cominciando a sembrare un vero e proprio gestore di memoria di sostituzione dell'heap.

+2

Non è la soluzione canonica al problema per creare un server, quali applicazioni client possono utilizzare? Molto più facile che futzing con memoria condivisa, che è improbabile che funzioni per i motivi che offri. –

+0

Concordato con Neil. – wheaties

+0

Sì. Ridisegnare l'applicazione sarebbe il modo più semplice per risolvere il problema. Sfortunatamente a causa di vincoli di progettazione dovuti alla compatibilità con altri componenti, non abbiamo questa opzione. – BillC

risposta

0

OSSP mm - allocazione memoria condivisa:

man 3 mm

1

Date un'occhiata a boost.interprocess.

+1

Come ho detto nel post, abbiamo esaminato la libreria Boost. Sfortunatamente non ha portato a termine ciò di cui avevamo bisogno. Ci conduce ad alcune risorse promettenti, tuttavia, come il link che ho citato nel post. – BillC

0

Come sono sicuro di aver trovato, questo è un problema molto complesso e molto difficile da implementare correttamente. Alcuni consigli dalle mie esperienze. Prima di tutto, vorrete sincronizzare l'accesso alle allocazioni di memoria condivisa usando i semafori. In secondo luogo, qualsiasi modifica degli oggetti condivisi da parte di più processi deve essere protetta anche dai semafori.Infine, è necessario pensare in termini di offset dall'inizio dell'area di memoria condivisa, piuttosto che con valori assoluti del puntatore, quando si definiscono gli oggetti e le strutture dati (è generalmente possibile che la memoria sia mappata a un indirizzo diverso in ogni processo allegato , anche se è possibile scegliere un indirizzo di mappatura fisso se necessario). Mettere tutto insieme in maniera robusta è la parte difficile. È facile che le strutture di dati basate su memoria condivisa si corrompano se un processo dovesse morire in modo imprevisto, quindi di solito è necessario un meccanismo di pulizia/ripristino.

+0

Hai esattamente ragione. Il problema è complesso ed è per questo che non vogliamo dover scrivere il codice da zero. – BillC

0

Anche studiare mutex e semafori. Quando due o più entità devono condividere memoria o dati, è necessario un meccanismo di "semaforo" per limitare l'accesso in scrittura a un solo utente.

+0

Grazie. Comprendiamo che questo deve essere thread-safe e avere implementato mutex per controllare l'accesso. Il problema principale che abbiamo è come assicurarsi che alcuni oggetti siano allocati nella memoria condivisa, insieme a qualsiasi oggetto che istanziano, mentre altre istanze degli stessi oggetti sono allocate localmente. – BillC

+0

Processo di missaggio: la memoria locale e condivisa come quella che descrivi sembra generalmente una ricetta per il disastro. Definire un protocollo di comunicazione tra processi più formale è probabilmente un approccio migliore. –