2013-05-30 5 views
8

Ich habe eine relativ komplexe Klasse in C++. Es funktioniert perfekt, wenn es in einem Prozess verwendet wird. Jetzt möchte ich jedoch, dass mehrere Prozesse eine Objektinstanz dieser Klasse gemeinsam nutzen können. Ein Prozess (Master) greift auf Lese- und Schreibfunktionen des Objekts zu, während die anderen beiden Prozesse (Slave) nur die Lesefunktionen verwenden. Ich möchte die Klasse so wenig wie möglich ändern. Bisher habe ich Singletons und Shared Memory in Betracht gezogen, aber keines scheint ideal oder einfach zu sein. Dies ist eine Forschungsanwendung, die nur von mir unter Linux verwendet wird. Was ist die einfachste mögliche Lösung?C++ Sharing einzelne Klasse Objekt zwischen mehreren Prozessen

Vielen Dank!

Edit: Um ganz klar zu sein, ist der Fragesteller interessiert, ein Objekt über mehr Prozesse teilen nicht Threads.

+1

Ich habe es nicht benutzt, aber Sie nicht erwähnen. org/doc/libs/1_53_0/doc/html/interprozess.html). – BoBTFish

+0

Sie können nach Shared Memory suchen. [Hier eine Frage zu SO] (http://stackoverflow.com/questions/5656530/how-to-use-shared-memory-with-linux-in-c), aber für 'C' (das kann auch für C++ funktionieren) – A4L

Antwort

1

Eine Idee könnte sein, Socket oder eine Socket-Bibliothek zu verwenden, um die Daten zwischen den Prozessen zu teilen. Eine Bibliothek, die dafür sehr praktisch zu sein scheint, könnte ØMQ sein. Sie können auch versuchen, Boost::Asio verwenden, die ein bisschen komplexer ist.

Sie können ein kleines Beispiel für ØMQ here finden.

0

Ich denke, die einfachste Kodierungslösung wäre ein Singleton mit einem globalen (oder Klasseninstanz) Mutex, obwohl der Singleton-Teil davon optional ist. Ich persönlich halte Singles für ein überstrapaziertes Idiom. Bis zu Ihnen, ob Sie denken, dass das in diesem Fall gutes Design ist oder nicht. Wirklich, das Hinzufügen des globalen Mutex ist alles was Sie brauchen.

Für den Interprozessabschnitt empfehle ich Boost.

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

3

Inter-Prozess-Kommunikation ist nie einfach. Sie möchten möglicherweise eine Bibliothek für IPC/RPC verwenden und nur die Funktion offenlegen, mit der die Slaves Daten lesen, nicht die gesamte Klasse.

Ich kann Ihnen keine guten Empfehlungen geben, weil ich nie eine Bibliothek gefunden habe, die es einfach gemacht hat und ich habe nicht viel Erfahrung damit.

1

Eine Option besteht darin, dass der Master- und der Slave-Prozess Instanzen desselben Objekts erstellen. Da der Master-Prozess der einzige sein wird, der dieses "gemeinsam genutzte" Objekt ändert, muss er die Slave-Prozesse nur auf alle Änderungen hinweisen, die er an dem "gemeinsam genutzten" Objekt vornimmt. Um dies zu tun, könnten Sie ein Messagingsystem einrichten, das der Master-Prozess verwenden wird, um Änderungen an dem gemeinsam genutzten Objekt mit den Slave-Prozessen zu kommunizieren. Der Nachteil hierbei ist, dass die Slave-Prozesse auf das gemeinsame Objekt verweisen können, wenn es nicht mit dem Master synchronisiert ist, aber dies ist ein häufiges Problem bei der Replikation. Sie können auch ein RPC-Overlay verwenden, um die Entwicklung/Wartung der Master/Slave-Anwendungen zu erleichtern.

Ich werde versuchen, ein sehr hohes Beispiel dieses Entwurfs unten zur Verfügung zu stellen.Verzeih mir, dass ich echten Code und Pseudo-Code Seite an Seite benutze; Ich wollte nicht vollständig Code zu diesem, aber auch nicht wollte, nur aus Kommentaren werden :)

Hier ist unser gemeinsames Objekt, das

sowohl in Master/Slave-Code definiert wird
struct sharedobj { 
    int var1; 
}; 

hier ist ein Beispiel des Master-Prozesses das gemeinsame Objekt und Pflanzgut Aktualisierung ändert

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); 
} 

hier ist die Funktion, die der Master-Änderungen an die Slaves ausbreitet;

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); 

    } 

} 

Und hier ist der Slave-Code, der diese Änderungen empfängt und sein "Shared" -Objekt aktualisiert; höchstwahrscheinlich läuft es in einem anderen Thread, so dass der Slave laufen kann, ohne anhalten zu müssen und nach Objekt-Updates zu suchen. //www.boost:

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); 

}