On 11.05.13 02.43, Heinz-Mario Fr�hbeis wrote:
> Vorab:
> Es geht mir ja einzig darum, da� nicht irgendein Programm, da� durch
> mein Hauptprogramm aufgerufen wird, mein Hauptprogramm mitrei�t, wenn es
> mal knallt. Und AFAIK kriegt man das mit Threads nicht hin...
Wenn man sauber testet, schon. Aber technisch hast Du recht. Wenn das
Testen nicht praktikabel oder unverh�ltnism��iger Mehraufwand ist, dann
bieten Prozesse definitiv eine wesentlich bessere Isolation.
Allerdings ist diese Isolation nahezu auf einen Schlag dahin, wenn beide
komplexe Objekte im Shared Memory ablegen. Wolltest Du sie Isolation
aufrecht erhalten, m�sste dein Rahmenprogram praktisch mit jedem bin�ren
Datenschrott, der zu jedem x-beliebigen Zeitpunkt in den Shared Memory
geschreiben wird, noch definiertes Verhalten aufweisen. Das
hinzubekommen ist sicher mehr Aufwand, als das Unterprogramm absturzfrei
zu bekommen.
Hei�t: f�r eine saubere Isolation, solltest Du jegliche Art von bin�ren
Schnittstellen zwischen Haupt- und Unterprozess vermeiden, oder
zumindest mit �u�erster Vorsicht einsetzen (also nur BLOBs und �hnliches).
> Ich versuche es mal anders:
> Mein Programm erstellt eine Klasse "IDA".
> In dieser Klasse wird das Programm konfiguriert.
> Zus�tzlich gibt es dann noch eine DynamicLibary "IDASection".so.
> Diese Libary enth�lt eine Klasse "IDASection", die die Klasse "IDA" als
> Friend f�hrt.
>
> Dann gibt es zus�tzliche externe Programme, die ebenfalls die Klasse
> "IDASection" nutzen sollen, aber *erst* nachdem sie von "IDA"
> initialisiert wurde (also ein Key wird �bergeben, und noch einige
> Kleinigkeiten).
> Deshalb muss die Klasse "IDASection" mit dem externen Programm
> kommunizieren k�nnen _und mit der Klasse "IDA".
> "IDASection" hat Funktionen, wie z. Bsp. "Create_IDASection()" (ein
> Fenster erstellen), etc.), wobei dann die Klasse "IDA" benachrichtigt
> wird, da� jetzt eine Sektion ge�ffnet wurde. Und sie soll, wenn z. Bsp.
> "Remove_IDASection()" aufgerufen wurde durch das externe Programm, eine
> Nachricht an die Klasse "IDA" senden, da� _diese Sektion beendet wurde.
Du Hast einen Denkfehler. Du brauchst in deinem Modell /drei/ Klassen.
IDA, IDSectionClient und IDASectionServer. Die letzteren beiden
kommunizieren �ber Messages oder �ber Request/Reply �ber die
Prozessgrenzen hinweg miteinander. F�r diese Kommunikation gelten die
oben genannten Einschr�nkungen bez�glich bin�rer Inhalte.
IDAServer und IDAClient sind aber komplett unterschiedliche Klassen.
IDAClient wird von IDA und dessen Programm verwaltet. IDAServer hingegen
ist dein Unterprogramm und stellt remote-f�hige Funktionen bereit, und
evtl. ein paar Notifications, wenn bestimmte Ereignisse (wie z.B.
Completion) eintreten.
> So will ich das haben...aber leider finde ich im Internet nichts
> Vergleichbares, wo ich mich durch ein Bsp. einarbeiten k�nnte.
Das liegt daran, dass es so nicht funktioniert. Du kannst nicht einfach
eine Klasse im Programm A erstellen und dann an Programm B �bergeben und
dann auch noch mit beiden Programmen gleichzeitig darin herumackern.
> Die Klasse "IDASection" der DynamicLibary "IDASection".so muss also
> irgendwie in ein SharedMemory...und ich wei� einfach nicht wie.
Mach das blo� nicht. Das ist sowas von undefiniertes Verhalten. Ich habe
nicht den Eindruck, dass Du tief genug in der systemnahen Programmierung
bzw. in den Implementierungsdetails deiner Compilerplattform drin
steckt, als das das mit definiertem Verhalten enden k�nnte.
> Wobei ich nat�rlich hoffe, da� ich unter SharedMenory das auch richtig
> verstehe, da� _zwei Prozesse auf _eine Ressource zugreifen k�nnen.
Ja, das passt schon, aber Klassen dulden out of the Box erst mal keine
fremden G�tter, da es zugeh�rige, versteckte Metadaten gibt, die
zus�tzliche Informationen halten, derer Du dir im Normalfall gar nicht
bewusst sein kannst. Das geht mit den Allocation-Heaps los, die man noch
selber durch konsequentes �berladen aller new/delete Operatoren im
Shared Memory implementieren kann. Aber damit ist der Spa� noch nicht
vorbei. Die �blicherweise von C++-Compiler genutzten RTTI-Informationen
wie z.B. VTables liegen im Private-Memory des jeweiligen Programms und
verweisen auch direkt auf compilierten Code in eben demselben private
Memory. Letzteres kannst Du nat�rlich mit deiner Dynamic Library
halbwegs einfangen. Dem liegt die Annahme zugrunde, dass die konstanten
Segmente einer DLLs aus Sicht aller Prozesse die sie nutzen auf
dieselben virtuellen Adressen geladen werden. Unter x86 mit gcc h�ttest
Du da vermutlich sogar Gl�ck. Aber es gibt auch Plattformen, wo jeder
Code per se nicht an absolute Adressen gebunden ist.
Allerdings muss Dir eins klar sein. Selbst wenn Du das am Ende sogar
hinbekommst, hast Du den Sinn der ganzen Aktion die Isolation von
Rahmen- und Unterprogrammen, komplett kompromittiert. Wenn z.B. ein
Unterprogramm just in dem Moment absemmelt, wo es ein Mutex zum Zugriff
auf die gemeinsamen Daten h�lt, hast Du einen Deadlock im
Rahmenprogramm. Wenn es durch einen Programmfehler die Datenstrukturen
im Shared Memory besch�digt, st�rzt das Rahmenprogramm mit gro�er
Wahrscheinlichkeit auch ab.
Du h�ttest letztlich dieselben Sicherheitsanforderungen zu bew�ltigen,
die auch f�r andere IPC-Mechanismen gelten. Mit allen Spielchen, wie
Buffer-Overuns etc. Und das �berl�sst man besser den Kernel- und
Framework-Programmierern.
> Was alles evtl passieren kann, und was evtl nicht...das ist mir im
> Moment vollkommen Schnurz. Mir w�re es wichtig, da� es _�berhaupt zu
> realisieren ist.
Nicht mit vertretbarem Aufwand.
> Mit Gru�
> Heinz-Mario <der einfach nicht glauben will, da� das nicht mit C++ und
> Co. zu realisieren ist> Fr�hbeis
Es /ist/ zu realisieren. Aber willst Du wirklich das Rad neu erfinden?
Nimm die eine dokumentierte RPC-Schnittstellenl�sung, und setzte darauf
auf. Daf�r gibt es Frameworks ohne Ende. Web-Services war nur ein
Vorschlag. Es gibt auch noch dutzende, komplett andere. CORBA, DBUS, was
auch immer. Aber Du solltest ein High-Level Framework nehmen, und nicht
auf unterster Ebene alles neu aufbauen.
Das einzige, was man noch ohne viel Overhead halbwegs direkt bedienen
kann, sind Message-Pipes mit kurzen String-Messages. (Bei l�nger wird es
schon wieder komplizierter, wegen der Paketierung.)
Als erstes, w�rde ich eine Liste der Befehle machen, die das
Hauptprogramm an die Server-Prozesse senden k�nnen soll (z.B. Init,
GetData, Cancel ...).
Dann die Ereignisse, die vom Unterprogramm bereitgestellt werden sollen
(z.B. CalculationCompleted). Dann braucht man zu jedem der Aufrufe die
Parameter in serialisierbarer Form (also am besten nur Strings). Wenn
die zu �bergebenden Datenstrukturen komplex sind, w�rde ich ein
XML-Format nehmen. Das ist per se serialisierbar und halbwegs sicher vor
Kompromittierung. Also XSD f�r Request und Reply basteln. Das XSD-kann
man dann in Frameworks importieren, die daraus den ben�tigten Code f�r
Client und Server erzeugen.
Andere Frameworks setzen auf anderen Protokolldefinitionen auf. Also
z.B. Methodensignaturen, wobei aber alle verwendeten Datentypen
serialisierbar sein m�ssen. Also faktisch nur int, string etc. oder halt
solche, f�r die man eine eigene Serialisierung bereitstellt.
Die Entscheidung f�r eine IPC-Technik w�rde ich erst treffen, wenn ich
die Anforderungen zusammen habe, und wei�, mit welchen Datentypen es
�ber IPC zu hantieren gilt.
Marcel