AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Konzept gesucht - Interprocess communication

Konzept gesucht - Interprocess communication

Ein Thema von Zacherl · begonnen am 8. Sep 2007 · letzter Beitrag vom 18. Jan 2008
Antwort Antwort
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#1

Konzept gesucht - Interprocess communication

  Alt 8. Sep 2007, 14:56
Hey,

ich möchte folgendes realisieren:

1 Prozess ist aktiv, welcher einen 2. startet. Dieser 2. Prozess soll prüfen ob Prozess 1 noch läuft und diesem gegebenenfalls neu starten.

Dabei möchte ich Memory Mapped Files verwenden. In Prozess 1 läuft ein Thread, welcher alle 5 Sekunden GetTickCount in das MMF schreibt. Prozess 2 guckt jede 10 Sekunden ob der ausgelesene Wert < GetTickCount + 10 ist. Wenn nicht wird Prozess 1 neu gestartet.

Wie findet ihr dieses Konzept? Könnte man es über Named Pipes evtl. einfacher lösen?

Gruß Florian
  Mit Zitat antworten Zitat
Reinhard Kern

Registriert seit: 22. Okt 2006
772 Beiträge
 
#2

Re: Konzept gesucht - Interprocess communication

  Alt 8. Sep 2007, 15:03
Zitat von Zacherl:
Hey,

ich möchte folgendes realisieren:

1 Prozess ist aktiv, welcher einen 2. startet. Dieser 2. Prozess soll prüfen ob Prozess 1 noch läuft und diesem gegebenenfalls neu starten.

Dabei möchte ich Memory Mapped Files verwenden. In Prozess 1 läuft ein Thread, welcher alle 5 Sekunden GetTickCount in das MMF schreibt. Prozess 2 guckt jede 10 Sekunden ob der ausgelesene Wert < GetTickCount + 10 ist. Wenn nicht wird Prozess 1 neu gestartet.

Wie findet ihr dieses Konzept? Könnte man es über Named Pipes evtl. einfacher lösen?

Gruß Florian
Hallo,

wozu GetTickCount austauschen? Es genügt doch, wenn P1 alle 5 sec eine Botschaft sendet "bin noch da" und P2 prüft das (mit einem Timer) nach dem Prinzip Watchdog - das geht sogar mit einer Windowsmessage. Wenn P2 mit einer Botschaft antwortet, können sie sich gegenseitig überwachen.

Gruss Reinhard
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

Re: Konzept gesucht - Interprocess communication

  Alt 8. Sep 2007, 15:13
Ich weiß nicht genau wie das ist bei MMFs. Der reingeschriebene Wert bleibt doch im File stehen, auch wenn ich ihn ausgelesen habe, oder nicht? Weil wenn ja, dann würde der Wert auch drin stehen bleiben, wenn P1 längst terminiert wurde.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.109 Beiträge
 
Delphi 12 Athens
 
#4

Re: Konzept gesucht - Interprocess communication

  Alt 18. Jan 2008, 22:54
(ich weiß, is schon ein bissl alt, aber Überschrift und Thema passen zu meinem Problem, also wozu einen neuen Thread aufmachen )

MMFs muß man ja nicht mit einer Datei verknüpfen und dann liegt nur eine virtuelle Datei im Arbeitsspeicher.

Wenn dann beide Prozesse beendet sind, dann wird der Speicher (also die Datei) freigegeben.


Aber für dein Problem ist es wohl wirklich am einfachsten sich Windowsnachrichten hin und eventuell zurückzuschicken.

A schickt alle 10 Sekunden eine Nachricht an B

und mißt die Zeit zur letzten empfangenen Nachricht ... z.B. 20-30 Sekunden keine Meldung von A, dann wird A neu gestartet.

> größere Zeit beim Prüfen, da Messages nicht unbedingt sofort ankommen und es mal mehr als 10 Sekunden dauern kann.






So, nun zu mir...

mein Programm hat schon eine IPC via WMs, aber nun bräuchteich noch eine bidirektionale Übertragung größerer Datenblöcke.

WM_COPYDATA geht ja nur zum Versenden und empfangen wirde bei der Implementierung wohl vollkommen ignoriert

also was wie Folgendes geht halt nicht.
Delphi-Quellcode:
X:Zeiger := ...;
X.MaxLen := 123456;
SendMessage(Wnd, WM_COPYDATA_RECIVE, @X, 0);

{ oder }

X := SendMessage(Wnd, WM_COPYDATA_RECIVE, 0, 0);
//X = sowas wie COPYDATASTRUCT
Eine nachricht al Anfrage zu senden und dann auf eine antwort z.B. per WM_COPYDATA zu warten ist auch nicht so optimal (Nachrichtenabarbeitungsreinfolge und Threadsicherheit würden da etwas leiden und müßten zusätzlich nochmals geprüft werden)

hab mich auch in letzter Zeit nach Com, ActiveX, Interfaces umgesehn, aber so richtig hab da noch icht durchgesehn

So wie Named-Pipes und Mail-Slots hat auch wieder andere Nachteile.

nunja und MMFs scheinen auch manchmal Probleme zu machen (z.B. kein Zugriff unter Vista u.a.)
Aber dennoch wollt ich's damit mal versuchen...

mein Code würde dann in etwa so aussehn:
- kleiner Testcode ohne (richtige) Fehlerbehandlung und Co.
- und noch nicht auf verschiedene Prozesse verteilt
das "Begin (* ... *)" bis "End;" stellt sozusagen jeweils den Messagehandler des Fremdprozesses dar
Delphi-Quellcode:
Const AllocSize = 64 * 1024; {diese größe wird dann auch noch dynamisch :wall: }

Var SourceMap, DestMap, H, S, R: THandle;
  Ps, Pd: Pointer{PAnsiChar};

Begin
  Try
    {MMF erstellen}
    SourceMap := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, AllocSize, nil);
    If SourceMap = INVALID_HANDLE_VALUE Then Exit;

    {was in die MMF reinschreiben ... zum Senden, falls nötig}
    Ps := MapViewOfFile(SourceMap, FILE_MAP_WRITE, 0, 0, 0);
    If Ps = nil Then Exit;
    // Copy(Ps, irgendwas)
    UnmapViewOfFile(Ps);

    {Handle der MMF für anderen Prozeß erstellen}
    {}If not DuplicateHandle(GetCurrentProcess, GetCurrentProcess, GetCurrentProcess, @H,
    {}  PROCESS_DUP_HANDLE, False, 0) Then Exit;
    //H := OpenProcess(PROCESS_DUP_HANDLE, False, GetCurrentProcessId);
    //If H = 0 Then Exit;
    S := SourceMap;
    Begin (* R := SendMessage(Wnd, WM_DUPLICATE_HANDLE, H, S); *)
      If not DuplicateHandle(H, S, GetCurrentProcess, @R,
        0, False, DUPLICATE_SAME_ACCESS) Then Exit;
    End;
    DestMap := R;

    {Nachricht senden}
    {und drüben die MMF auslesen/bearbeiten}
    H := DestMap;
    Begin (* R := SendMessage(Wnd, WM_MACHWAS, wmDiesUndDas, H); *)
      Pd := MapViewOfFile(H, FILE_MAP_READ{FILE_MAP_WRITE}, 0, 0, 0);
      If Pd = nil Then Exit;
      // Copy(Pd), oder so
      UnmapViewOfFile(Pd);
      CloseHandle(DestMap);
    End;

    {MMF auslesen ... zum Empfangen, falls nötig}
    Ps := MapViewOfFile(SourceMap, FILE_MAP_READ, 0, 0, 0);
    // Copy(irgendwas, Ps)
    UnmapViewOfFile(Ps);

    {MMF freigeben}
    CloseHandle(SourceMap);
  Finally
    Application.MessageBox(PChar(SysErrorMessage(GetLastError)), PChar(Caption));
  End;
End;
müßte doch so in etwa funktionieren ... denk ich mal.



nun ist mir dabei aber was aufgefallen ...

weil ich keine Names-MMFs verwenden kann (ein/zwei Günde nachfolgend) übergebe ich nun statt einen "Pointers auf die Daten" den Handle zur MMF.

... und da ich ja zur Handleübergabe das Prozeßhandle benötige, könnte ich doch eigentlich gleich statt PROCESS_DUP_HANDLE einfach PROCESS_VM_OPERATION+PROCESS_VM_READ+PROCESS_VM_WR ITE verwenden
und dann direkt via VirtualAllocEx+Read/WriteProcessMemory zugreifen?

unter Anderem könnte dann die angefragte Anwendung dann selber die Größe des Rückgabepuffers festlegen und ich müßte nicht vorher über eine zusätzliche Abfrage rausbekommen wieviel Speicher die MMF mindestens haben muß.


Gründe + grobe Programmstruktur:
- es gibt einen "Clienten", welcher von einem/mehreren "Servern" gesteuert wird, wobei die Server nicht wissen (müssen) das/ob es andere gibt.
- die Server können (müssen aber nicht) sich per WM beim Clienten anmelden und dort ein Handle und eine WM-ID hinterlegen, worüber sie eine Mitteilung bekommen, sobald sich was am Datenbestand durch irgendwen verändert hat.
- der Client steht immer auf Empfang und jeder Server kann ohne Voranmeldung senden
- es besteht aber die Möglichkeit zugriffe die Zur änderung der Daten im Clienten führen zu sperren (kann ein Server explizit beantragen, falls nötig)
- es können aber auch mehrere Clienten existieren (zwar sehr unwahrscheinlich, aber dennoch hab ich diese Möglichkeit offengelassen)

Dank der WM (SendMessage und Co) ist das ganze aber dennoch Threadsave, da schließlich immer nur eine WM zum selben Zeitpunkt verarbeitet wird,
was bei bidirektionaler Kommunikation per WM wiederum verlorengehen kann (drum kein WM_COPYDATA)

> Server sendet neue Daten oder fragt welche ab
> Client gibt bei Änderung über PostMessage (nur Integer und Co.) an registrierte Sever eine Meldung aus
= also keine gegenseitige Blockierung möglich


Mehrere Clienten/Server, darum keine Named-Pipes und Named-MMFs ... wie sollte ich da denn die Namen versenden, da ich ja grad zum Versenden/Empfangen von Namen und Dergleichen dieses benötige ...
wär ja so, als ließe ich das Huhn sein eigenes Ei legen lassen



Was meint ihr?
- die MMFs weiter ausbauen (hab's erstmal aufgehört und andere Möglichkeiten betrachtet, aber es ist schon was vorhanden)
- Direktzugriff (weniger Code = fehlerunanfälliger und dann auch noch ein einfacheres Speichermanagement)
oder habt ihr bessere Ideen?
- was ganz anderes (wenn ich Pech hab, darf ich da auch noch die gesamte Nachrichtenbehandlung und Programmstruktur ändern)


Ach ja, sollte die Kommunikation nur innerhalb des PCs (kein Netzwerk) und der selben Benutzerebene ablaufen ... jedenfalls fällt mir kein wirklcher Grund ein, warum beides/alles weiter auseinander sein sollte
und Vor-Win2000pro unterstütz ich auch nicht mehr explizit (also wenn es da nicht läuft ... egal )




Es gibt halt unzählige Möglichkeiten mit massig Vorteilen, aber wenn man die dann versucht auf ein bestimmtes Problem anzuwenden, dann hat alles irgendwie nur noch Nachteile
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz