Shared Memory

martinpriebe

Erfahrenes Mitglied
Hallo,

ich suche Hilfe um das Thema Shared Memory.

Es geht dabei um Daten möglichst schnell zwischen 2 Prozessen auszutauschen.
Ich weiß, im .Net gibt es Remoting.
Aber das ist, denke ich, nicht schnell genug.
Es geht um Bilddateien mit einer Größe von 1 bis 10 MB.

Ein Prozess erstellt das Bild und der andere holt es ab.
Das heißt die Dateien ändern sich auch recht schnell und Prozess 2 muss natürlich gesagt bekommen das er ein neues Bild abholen soll.

Ich denke nicht das ich mit Remoting da weiterkomme.

Dann dachte ich an Shared Memory in dem ein Prozess rein schreibt und der andere raus liest.
Immer ein fest definierter Speicherbereich der allokiert wird.
Leider war das bisher nur eine Idee aber im Prinzip wäre das der schnellste Austausch von Dateien.


Hat jdm. Tipps in der Richtung für mich ?

Oder evt. auch eine andere Idee ....


mfg
Martin
 
Moin,

habe gerade mal 'ne Runde gegoogelt und hätte folgenden Tipp:

Man kann in C# mit Zeigern (pointern) arbeiten. Dazu muss man den entsprechenden Code als unsafe deklarieren.
Wenn du nun dem anderen Prozess die Speicheradresse, sowie die Größe der Bilddatei mitteilst könntest du auf diese Weise mit beiden Prozessen auf die selbe Stelle ich Speicher zugreifen.

Soweit meine Theorie... obs geht, keine Ahnung!

Andere Frage: Was ist das für ein Programm, dass du zwei Prozesse auf einem Rechner hast, die Daten miteinander ausstauschen müssen?
 
da geht es um Bildverarbeitung und die Trennung von Abarbeitung und Anzeige.

Es gibt einen Dienst der mit der Kamera kommuniziert, Bilder aufnimmt, auswertet und die Ergebnisse weiterleitet.

Ein anderer Prozess ist die reine Ansicht. Ergebnisbild + Werte aus der Datenbank.

Das Framework das ich nutze (aus unserer Fa) ist so aufgebaut.
Bisher habe ich alle in der reinen Ansicht aber das hat einige Nachteile.
Deshalb muss ich es trennen.


tja logisch klingt das schon nur wie ich das machen soll - da habe ich noch keinen Plan.
 
ich probier das mal aus mit dem Memory Mapped File ..
Ergebnisse poste ich später ...


das mit der Zwischenablage ... ich weiß nicht ob das das ist was ich suche.
Bzw. ob das hilft.
Ich schau es mir aber ebenfalls mal an.


danke an Euch bis dahin
 
Lösung

Hier die Lösung ...
Erst serialisieren und dann in den Bereich kopieren mit CopyMemory.

Ich habe einige Codeteile weg gelassen ..
Wenn Interesse besteht poste oder maile ich sie noch.

hier die nötigen Sachen.

[DllImport("kernel32.dll")]
public static extern void CopyMemory(IntPtr dst, byte[] src, int len);
[DllImport("kernel32.dll")]
public static extern void CopyMemory(byte[] dst, IntPtr src, int len);


Server:
...
IntPtr mappedViewHandle = MapViewOfFile(mmfHandle, (uint)FILE_MAP_WRITE, 0, 0, 0);

System.IO.MemoryStream stream = new System.IO.MemoryStream();

System.Runtime.Serialization.Formatters.Soap.SoapFormatter formatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
formatter.Serialize(stream, bmpScreenshot);

byte[] bitmapBytes = stream.ToArray();

CopyMemory(mappedViewHandle, bitmapBytes, bitmapBytes.Length);



Und auf Client Seite:

IntPtr mappedViewHandle = MapViewOfFile(mappedFileHandle, (uint)FILE_MAP_READ, 0, 0, 0);

byte[] bitmapBytes = new byte[642166];

CopyMemory(bitmapBytes, mappedViewHandle, 642166);

System.IO.MemoryStream stream = new System.IO.MemoryStream(bitmapBytes);

System.Runtime.Serialization.Formatters.Soap.SoapFormatter formatter = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
Bitmap bmp = (Bitmap) formatter.Deserialize(stream);

pictureBox1.Image = bmp;



mfg
Martin
 
die kurze Fassung

so und nun das ganze geht auch schneller ohne Serialiserung.
reiner memorystream

Bild to Byte[]:

MemoryStream stream = new MemoryStream();
bild.Save(stream, ImageFormat.Bmp);
stream.Flush();
byte[] bytes =stream.ToArray();


und umgekehrt:

System.IO.MemoryStream stream = new System.IO.MemoryStream(bitmapBytes);
Bitmap bmp = (Bitmap) Image.FromStream(stream);


genauso kann man die Funktion CopyMemory durch Marshal.Copy ersetzen.


Somit wird das gnaze ziemlich einfach und auch recht schnell.
1 MB Bild in 15ms rüber und in 10ms abgeholt und angezeigt.
10MB Bild in 150ms erstellt und in 90ms wieder zurück
Also Geschwindigkeit scheint analog zur Größe zu sein.

Bei Interesse maile ich auch gerne den SourceCode.

mfg
MArtin
 
knapp 160 Zeilen für Server und nochmal 130 für den Client.
Natürlich mit Schnick-Schnack außen rum.

[edited]
jetzt werden es noch ein paar mehr, da ich noch Events erstelle.
Der eine Prozess erstellt das Event und feuert es und der andere Prozess wartet auf das Event um dann den Speicher auszulesen.
Das klappt bisher sub-optimal.
Events an sich geht (named events) - nur müßte ich einen Parameter mit übertragen.
Und da haperts noch.

[edited]
das hat sich jetzt auch erledigt.
Den Parameter zum übergeben (Bytearraygröße des Bitmaps) übergebe ich in den ersten 4 Bytes des Speichers.
Erst wird der ausgelesen und anhand davon der Rest.
Named events mache ich CreateEvent und OpenEvent.

ich denke jetzt ist es nahezu einsatzbereit.

mfg
Martin
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück