Memory mapping unter Linux

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut

Re: Memory mapping unter Linux

Beitragvon mse » 17. Sep 2017, 16:46 Re: Memory mapping unter Linux

MitjaStachowiak hat geschrieben:Hast du ein Beispiel dazu?

Hier:
https://gitlab.com/mseide-msegui/mseuni ... /sharedmem
Funktioniert bei mir auf 32 und 64 Bit Linux.
Edit: Habe das Beispiel erweitert.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Zuletzt geändert von mse am 18. Sep 2017, 09:23, insgesamt 1-mal geändert.
mse
 
Beiträge: 1677
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.4.2,git master FPC 3.0,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon m.fuchs » 17. Sep 2017, 21:48 Re: Memory mapping unter Linux

MitjaStachowiak hat geschrieben:http zur inter-prozess-kommunikation ist irgendwie nicht der richtiger Weg, finde ich. Es soll hier ja nicht über Netzwerk laufen.

HTTP ist eine Möglichkeit für Interprozesskommunikation. Im Gegensatz zu Shared-Memory ist es halt eine Nachrichten-basierte Form.
Hat den Vorteil der besseren Trennung der Prozesse und möglicher Skalierbarkeit. Ist aber langsamer, wenn es um große Datenmengen geht.

Ob es für dich sinnvoll ist, kann ich dir nicht sagen. Dazu ist von dem Anwendungsfall zu wenig bekannt.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
m.fuchs
 
Beiträge: 1676
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.6, FPC 3.0) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon MitjaStachowiak » 20. Sep 2017, 00:03 Re: Memory mapping unter Linux

So, ich konnte das Beispiel von mse erfolgreich mit mseide und in vereinfachter Form mit Lazarus kompilieren und ein Handle <> -1 erhalten. Warum es in meinem Programm noch nicht geht, weiß ich nicht, aber das sollte ich auch noch hin bekommen.

Wenn's gut läuft, kann ich am Ende ein Shared-Memory-Beispiel machen, das auf Windows und Linux gleich funktioniert.
MitjaStachowiak
 
Beiträge: 320
Registriert: 15. Mai 2010, 12:46
OS, Lazarus, FPC: Win 7, Lazarus 32/64 (Codetyphon-Edition) | 
CPU-Target: 64 bit
Nach oben

Beitragvon marcov » 20. Sep 2017, 07:37 Re: Memory mapping unter Linux

m.fuchs hat geschrieben:
MitjaStachowiak hat geschrieben:http zur inter-prozess-kommunikation ist irgendwie nicht der richtiger Weg, finde ich. Es soll hier ja nicht über Netzwerk laufen.

HTTP ist eine Möglichkeit für Interprozesskommunikation. Im Gegensatz zu Shared-Memory ist es halt eine Nachrichten-basierte Form.
Hat den Vorteil der besseren Trennung der Prozesse und möglicher Skalierbarkeit. Ist aber langsamer, wenn es um große Datenmengen geht.


(Aber mit das öffnen einer HTTP Server macht man sich möglich ein Ziel des Antivirens, AppArmor usw)
marcov
 
Beiträge: 999
Registriert: 5. Aug 2008, 08:37
Wohnort: Eindhoven (Niederlande)
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk) | 
CPU-Target: 32/64,PPC(+64), ARM
Nach oben

Beitragvon MitjaStachowiak » 21. Sep 2017, 01:31 Re: Memory mapping unter Linux

Ok, ich habe eine kleine Unit geschrieben, die ein simples MemmoryMapping ohne extravagante Zugriffsbeschränkungen etc. erstellen kann:
Code: Alles auswählen
 
unit sharedmem;
 
{
 This unit provides simple memory mappings for inter-process communication on
 Windows and Linux in a consistent way.
}

 
{$mode objfpc}{$h+}
 
interface
 
uses
 Classes, SysUtils{$IFDEF Windows}, Windows{$ENDIF}{$IFDEF Unix}, baseunix {, ipc}{$ENDIF};
 
function OpenFileMappingSimple(const name:ShortString) : THandle;
function CreateFileMappingSimple(const name:ShortString; Size:QWord) : THandle;
function MapViewOfFileSimple(mapping:THandle; Size:QWord) : Pointer;
procedure UnmapViewOfFileSimple(adr:Pointer; Size:QWord);
procedure CloseFileMappingSimple(const name:ShortString; mapping:THandle);
 
 
implementation
 
{$IFDEF Unix}
const
 {$ifdef FPC}clib = 'c';{$else}clib = 'libc.so.6';{$endif}
 {$ifdef linux}shmlib = 'rt';{$else}shmlib = clib;{$endif}
 
 O_ACCMODE  = $00003;
 O_RDONLY   = $00000;
 O_WRONLY   = $00001;
 O_RDWR     = $00002;
 O_CREAT    = $00040;//&00100;
 O_EXCL     = $00080;//&00200;
 O_NOCTTY   = $00100;//&00400;
 O_TRUNC    = $00200;//&01000;
 O_APPEND   = $00400;//&02000;
 O_NONBLOCK = $00800;//&04000;
 O_NDELAY   = O_NONBLOCK;
 O_SYNC     = $01000;//&010000;
 O_FSYNC    = O_SYNC;
 O_ASYNC    = $02000;//&020000;
 O_CLOEXEC  = $80000;
 
 S_ISUID = $800;
 S_ISGID = $400;
 S_ISVTX = $200;
 
 S_IRUSR = $100;
 S_IWUSR = $80;
 S_IXUSR = $40;
 
type
{$ifdef cpu64}
  size_t = QWord;
  off_t = QWord;
{$else}
  size_t = Cardinal;
  off_t = Cardinal;
{$endif}
 
function shm_open(name: pchar; oflag: longint; mode: Cardinal): longint; cdecl; external shmlib name 'shm_open';
function shm_unlink(name: pchar): longint; cdecl; external shmlib name 'shm_unlink';
function mmap(addr: pointer; lengthint: size_t; prot: longint; flags: longint; fd: longint; offset: off_t): pointer; cdecl; external clib name 'mmap';
function munmap(addr: pointer; length: size_t): longint; cdecl; external clib name 'munmap';
{$ifdef linux}
function ftruncate64(handle: integer; size: int64): integer; cdecl; external clib name 'ftruncate64';
{$else}
function ftruncate64(handle: integer; size: int64): integer; cdecl; external clib name 'ftruncate';
{$endif}
{$endif}
 
 
 
 
 
 
function OpenFileMappingSimple(const name: ShortString): THandle;
var _name : ShortString;
begin
 {$IFDEF Windows}
  _name := name+#0#0;
  Result := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, PChar(@_name[1]));
 {$ENDIF}
 {$IFDEF Unix}
  _name := '/'+name+#0#0;
  Result := shm_open(PChar(@_name[1]), O_RDWR, S_IRUSR or S_IWUSR); //Result := shmget(PInteger(@name[1])^, Size, 0);
  if (Result < 0) then Result := 0
  else Result := Result + 1;
 {$ENDIF}
end;
 
function CreateFileMappingSimple(const name: ShortString; Size: QWord): THandle;
var _name : ShortString;
begin
 {$IFDEF Windows}
  _name := name+#0#0;
  Result := CreateFileMapping(INVALID_HANDLE_VALUE, Windows.LPSecurity_ATTRIBUTES(0), PAGE_READWRITE, 0, Size, PChar(@_name[1]));
 {$ENDIF}
 {$IFDEF Unix}
  _name := '/'+name+#0#0;
  Result := shm_open(PChar(@_name[1]), O_RDWR or O_CREAT, S_IRUSR or S_IWUSR); //Result := shmget(PInteger(@name[1])^, Size, IPC_CREAT or 0777);
  if (Result < 0) then Result := 0
  else begin
   ftruncate64(Result, Size);
   Result := Result + 1;
  end;
 {$ENDIF}
end;
 
function MapViewOfFileSimple(mapping: THandle; Size: QWord): Pointer;
begin
 {$IFDEF Windows}
  Result := MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
 {$ENDIF}
 {$IFDEF Unix}
  Result := Fpmmap(nil, Size, PROT_READ or PROT_WRITE, MAP_SHARED, mapping-1, 0); //Result := shmat(mapping, nil, 0);
 {$ENDIF}
end;
 
procedure UnmapViewOfFileSimple(adr: Pointer; Size: QWord);
begin
 {$IFDEF Windows}
  UnmapViewOfFile(adr);
 {$ENDIF}
 {$IFDEF Unix}
  FPMUnMap(adr, Size); //shmdt(adr);
 {$ENDIF}
end;
 
procedure CloseFileMappingSimple(const name: ShortString; mapping: THandle);
var _name:ShortString;
begin
 {$IFDEF Windows}
  CloseHandle(mapping);
 {$ENDIF}
 {$IFDEF Unix}
  _name := '/'+name+#0#0;
  shm_unlink(PChar(@_name[1])); //shmctl(mapping, IPC_RMID, nil);
 {$ENDIF}
end;
 
end.
 


Zur Verwendung:
Code: Alles auswählen
 
// required infos
type
 TMapInfo = record
  Wert1 : Integer;
  Wert2 : Integer;
  //...
 end;
const
 mmfName = 'MessdatenUpload';
var
 mmfHandle : THandle;
 mmfErr : Boolean = false;
 isFirstProcess : Boolean = false;
 
// open/create filemapping
mmfHandle := OpenFileMappingSimple(mmfName);
if (mmfHandle = 0) then begin // auf Linux wird das native Handle +1 gezählt, sodass der invalid-Wert auch 0 ist
 inf.isFirstProcess := true;
 mmfHandle := CreateFileMappingSimple(mmfName, SizeOf(TMapInfo));
 if (mmfHandle = 0) then mmfErr := true;
end;
if (not mmfErr) then begin
 mmf := MapViewOfFileSimple(mmfHandle, SizeOf(TMapInfo));
 // do something with the mapping
end;
 
// close filemapping
if (not mmfErr) then begin
 UnmapViewOfFileSimple(mmf, SizeOf(TMapInfo));
 CloseFileMappingSimple(mmfName, mmfHandle);
end;
mmf := nil;
mmfHandle := 0;
 
MitjaStachowiak
 
Beiträge: 320
Registriert: 15. Mai 2010, 12:46
OS, Lazarus, FPC: Win 7, Lazarus 32/64 (Codetyphon-Edition) | 
CPU-Target: 64 bit
Nach oben

• Themenende •
Vorherige

Zurück zu Freepascal



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron
porpoises-institution
accuracy-worried