2013-05-30 9 views
8

Ho una classe relativamente complessa in C++. Funziona perfettamente se utilizzato all'interno di un unico processo. Tuttavia, ora voglio che più processi siano in grado di condividere un'istanza di oggetto di questa classe. Un processo (Master) accederà alle funzioni di lettura e scrittura dell'oggetto, mentre gli altri 2 processi (Slave) utilizzeranno solo le funzioni di lettura. Voglio modificare la classe il meno possibile. Finora ho considerato singleton e memoria condivisa, ma nessuno dei due sembra ideale o diretto. Questa è un'applicazione di ricerca che sarà sempre usata da me solo su Linux. Qual è la soluzione più semplice possibile?C++ condivisione di oggetti di classe singola tra più processi

Grazie mille!

Modifica: Per essere assolutamente chiaro, il richiedente è interessato a condividere un oggetto su più processi, non discussioni.

+1

non l'ho usato, ma voi non parlare di essere a conoscenza di [Boost.Interprocess] (http: //www.boost. org/doc/librerie/1_53_0/doc/html/interprocess.html). – BoBTFish

+0

Potrebbe essere necessario cercare 'memoria condivisa'. [Qui una domanda su SO] (http://stackoverflow.com/questions/5656530/how-to-use-shared-memory-with-linux-in-c) ma per 'C' (witch potrebbe funzionare anche per C++) – A4L

risposta

1

Un'idea potrebbe essere quella di utilizzare socket o una libreria socket per condividere i dati tra i processi. Una libreria che sembra essere molto utile potrebbe essere ØMQ. Puoi anche provare a usare Boost::Asio che è un po 'più complesso.

È possibile trovare un piccolo esempio per ØMQ here.

0

Penso che la soluzione di codifica più semplice sia un singleton con un mutex globale (o di istanza di classe), sebbene la parte singleton sia opzionale. Personalmente ritengo che i singleton siano un idioma abusato. Fino a voi se pensate che sia un buon design in questo caso o no. In realtà, aggiungere il mutex globale è tutto ciò di cui hai bisogno.

Per la porzione di interprocesso, consiglio boost.

http://www.boost.org/doc/libs/1_36_0/doc/html/interprocess/synchronization_mechanisms.html#interprocess.synchronization_mechanisms.semaphores.semaphores_interprocess_semaphores

3

comunicazione tra processi non è mai semplice. Si consiglia di utilizzare una libreria per IPC/RPC ed esporre solo la funzione che gli slave utilizzano per leggere i dati, non l'intera classe.

Non posso darti alcuna raccomandazione perché non ho mai trovato una libreria che lo abbia reso semplice e non ho molta esperienza con esso.

1

Un'opzione è che entrambi i processi master e slave creano istanze dello stesso oggetto. Poiché il processo principale sarà l'unico a modificare questo oggetto "condiviso", deve solo avvisare i processi di slave su qualsiasi modifica apportata all'oggetto "condiviso". Per fare ciò, è possibile configurare un sistema di messaggistica che verrà utilizzato dal processo master per comunicare le modifiche all'oggetto condiviso con i processi slave. Lo svantaggio qui è che i processi slave possono fare riferimento all'oggetto condiviso quando non è sincronizzato con il master, ma questo è un problema comune nella replica. Inoltre, è possibile utilizzare una sovrapposizione RPC per rendere le applicazioni master/slave più facili da sviluppare/mantenere.

Proverò a fornire un esempio di livello molto elevato di questo disegno di seguito.Perdonami per aver utilizzato codice reale e codice psuedo fianco a fianco; Non volevo pienamente codice di questo, ma anche non voleva che solo essere costituito da commenti :)

Ecco il nostro oggetto condiviso che viene definito sia in codice master/slave

struct sharedobj { 
    int var1; 
}; 

Ecco un esempio del processo di aggiornamento del maestro oggetto condiviso e propagazione delle modifiche

int counter = 0; 
sharedobj mysharedobj; 
while(true){ 
    //update the local version first 
    mysharedobj.var1 = counter++; 

    //then call some function to push these changes to the slaves 
    updateSharedObj(mysharedobj); 
} 

Ecco la funzione che propaga i cambiamenti del master agli slave;

updatedSharedObj(sharedobj obj){ 

    //set up some sort of message that encompasses these changes 
    string msg = "var1:" + the string value of obj.var1; 

    //go through the set of slave processes 
    //if we've just done basic messaging, maybe we have a socket open for each process 
    while(socketit != socketlist.end()){ 

    //send message to slave 
    send(*socketit, msg.c_str(),msg.length(),0); 

    } 

} 

Ed ecco il codice slave che riceve queste modifiche e aggiorna il suo oggetto "condiviso"; molto probabilmente eseguito in un altro thread in modo che lo slave possa essere eseguito senza dover interrompere e controllare gli aggiornamenti dell'oggetto.

while(true){ 

    //wait on the socket for updates 
    read(mysock,msgbuf,msgbufsize,0); 

    //parse the msgbuf 
    int newv1 = the int value of var1 from the msg; 

    //if we're in another thread we need to synchronize access to the object between 
    //update thread and slave 
    pthread_mutex_lock(&objlock); 

    //update the value of var1 
    sharedobj.var1 = newv1; 

    //and release the lock 
    pthread_mutex_unlock(&objlock); 

}