SharedMemory

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

Danke für die Info ...

Damit kann ich dann schon mal eine "mögliche Fehlerquelle" ausschließen...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Blackskyliner
Beiträge: 532
Registriert: 28.07.2005 00:54
Wohnort: /home/Blackskyliner/

Beitrag von Blackskyliner »

Wäre mir Rechten natürlich extrem genial, da dann auch etwas unerfahrene User Multithread mit einem Gemeinsamen Speicherpool programmieren könnten.

Ich wüßte z.B. nicht wie ich, wenn ich in dynamischen geladenen DLL's, die in das Programm geladen werden eine Threadsicherheit einbauen sollte ohne dass die DLL zuviel vom Syntax her vorgegeben bekommt.

Wenigstens ein lock() und unlock() wären was nettes =)
Keine meiner Antworten ist endgültig, es kann passieren, dass ich den so eben geposteten Beitrag noch mehrmals ändere, um Doppelposts zu umgehen.
_________________
Purebasic Windows 7 x64 & Linux (Ubuntu 10.04LTS) 4.50[x64|x86] Nutzer
_________________
Projekte: YAED - Yet another Event Dispatcher
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: SharedMemory

Beitrag von ts-soft »

Update für PB5.20 als Module:

Code: Alles auswählen

DeclareModule FileMap
  Declare Create(Name.s, Size.i)
  Declare Open(Name.s)
  Declare Close(*Mem)
EndDeclareModule

Module FileMap
  Global hMap.i
  
  Procedure Create(Name.s, Size.i)
    hMap = CreateFileMapping_(#INVALID_HANDLE_VALUE, 0, #PAGE_READWRITE | #SEC_COMMIT | #SEC_NOCACHE, 0, Size, @Name)
    If hMap
      ProcedureReturn MapViewOfFile_(hMap, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
    EndIf    
  EndProcedure
  
  Procedure Open(Name.s)
    hMap = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, 0, @Name)
    If hMap
      ProcedureReturn MapViewOfFile_(hMap, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
    EndIf
  EndProcedure
  
  Procedure Close(*Mem)
    UnmapViewOfFile_(*Mem)
    CloseHandle_(hMap)  
  EndProcedure
  
EndModule
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: SharedMemory

Beitrag von Bisonte »

sieht gut aus. Scheint nur so, als würde *mem\quit aus dem Beispiel im ersten Post schon #True
ist, wenn man es nicht selbst definiert.

Ich meine :
Sender.pb

Code: Alles auswählen

XIncludeFile "_mod_SharedMemory.pbi"

Structure myMem
  text.s{23}
  quit.l
EndStructure

; test
Define *mem.myMem = FileMap::Create("MyMemory", SizeOf(myMem))

If *mem
  *mem\text = "Feel the ..Pure.. Power"
  *mem\quit = #False ; <-- ohne dem ist das unten eine Endlosschleife
  
  While *mem\quit = #False
    Delay(100)
  Wend
  FileMap::Close(*mem)
  MessageRequester("MyMemory", "Client hat quit gesetzt")
EndIf
Empfänger.pb

Code: Alles auswählen

XIncludeFile "_mod_SharedMemory.pbi"

Structure myMem
  text.s{23}
  quit.l
EndStructure

; test
Define *mem.myMem = FileMap::Open("MyMemory")

If *mem
  MessageRequester("MyMemory", *mem\text)
 
  *mem\quit = #True
  FileMap::Close(*mem)
EndIf
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: SharedMemory

Beitrag von ts-soft »

Funktioniert wie es soll :wink:
Erst Sender starten, dann Client, dann Messagebox Client schliessen und dann Messagebox Sender schliessen.

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: SharedMemory

Beitrag von Bisonte »

Ja genau so wie ich die beiden sources hingeschrieben hab läuft es. Aber wenn man das *mem\Quit = #False beim Ersteller auskommentiert
schliesst der sich nicht mehr. Endlosschleife.
In deinem Ursprungsbeispiel war *mem\Quit nicht explizit gesetzt, weil wir ja annehmen können das eine nicht extra gesetzte Variable der 0 entspricht...

Zumindest bei mir ist das so... das wollt ich nur angemerkt haben.
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: SharedMemory

Beitrag von ts-soft »

*mem\quit ist mit oder ohne Deiner zugefügten Zeile erstmal 0, sehe das Problem also nicht.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: SharedMemory

Beitrag von mk-soft »

Mal eine Erweiterung mit Security.
Es gab Probleme um mit Diensten Daten auszutauschen. Der Path muss in diesen fall im Dienst mit "Global\..." beginnen und im Dienst das FileMap Attribut Security angelegt werden.

Thread http://www.purebasic.fr/german/viewtopi ... =6&t=28988

Update
Man konnte vor nicht mehrere SharedMemory anlegen da hMap einmalig Global war. Wird jetzt in über eine NewMap verwaltet

Code: Alles auswählen

DeclareModule FileMap
  Declare Create(Name.s, Size.i, Security = #False)
  Declare Open(Name.s)
  Declare Close(*Mem)
EndDeclareModule

Module FileMap
  
  Global NewMap hMap.i()
  
  Global SA.SECURITY_ATTRIBUTES
  Global pSD.SECURITY_DESCRIPTOR
  Global IsInitSecurity
  
  Procedure Create(Name.s, Size.i, Security = #False)
    
    Protected handle, *mem
    
    If Security
      If Not IsInitSecurity
        If Not InitializeSecurityDescriptor_(@pSD, #SECURITY_DESCRIPTOR_REVISION)
          ProcedureReturn 0
        EndIf
        If Not SetSecurityDescriptorDacl_(@pSD, #True, #Null, #False)
          ProcedureReturn 0
        EndIf
        SA\nLength = SizeOf(SA)
        SA\lpSecurityDescriptor = @pSD
        SA\bInheritHandle = #True
        IsInitSecurity = #True
      EndIf
      handle = CreateFileMapping_(#INVALID_HANDLE_VALUE, @SA, #PAGE_READWRITE | #SEC_COMMIT | #SEC_NOCACHE, 0, Size, @Name)
    Else
      handle = CreateFileMapping_(#INVALID_HANDLE_VALUE, 0, #PAGE_READWRITE | #SEC_COMMIT | #SEC_NOCACHE, 0, Size, @Name)
    EndIf
    
    If handle
      *mem = MapViewOfFile_(handle, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
      hMap(Str(*mem)) = handle
      ProcedureReturn *mem
    EndIf   
  EndProcedure
 
  Procedure Open(Name.s)
    
    Protected handle, *mem
    
    handle = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, 0, @Name)
    If handle
      *mem = MapViewOfFile_(handle, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
      hMap(Str(*mem)) = handle
      ProcedureReturn *mem
    EndIf
  EndProcedure
 
  Procedure Close(*Mem)
    Protected result
    
    UnmapViewOfFile_(*Mem)
    result = CloseHandle_(hMap(Str(*Mem)))
    DeleteMapElement(hMap(), Str(*Mem))
    ProcedureReturn result
  EndProcedure
 
EndModule
:allright:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: SharedMemory

Beitrag von ts-soft »

Update für PB5.40

Code: Alles auswählen

DeclareModule FileMap
  Declare Create(Name.s, Size.i, Security = #False)
  Declare Open(Name.s)
  Declare Close(*Mem)
EndDeclareModule

Module FileMap
 
  Global NewMap hMap.i()
 
  Global SA.SECURITY_ATTRIBUTES
  Global pSD.SECURITY_DESCRIPTOR
  Global IsInitSecurity
 
  Procedure Create(Name.s, Size.i, Security = #False)
   
    Protected handle, *mem
   
    If Security
      If Not IsInitSecurity
        If Not InitializeSecurityDescriptor_(@pSD, #SECURITY_DESCRIPTOR_REVISION)
          ProcedureReturn 0
        EndIf
        If Not SetSecurityDescriptorDacl_(@pSD, #True, #Null, #False)
          ProcedureReturn 0
        EndIf
        SA\nLength = SizeOf(SA)
        SA\lpSecurityDescriptor = @pSD
        SA\bInheritHandle = #True
        IsInitSecurity = #True
      EndIf
      handle = CreateFileMapping_(#INVALID_HANDLE_VALUE, @SA, #PAGE_READWRITE | #SEC_COMMIT | #SEC_NOCACHE, 0, Size, Name)
    Else
      handle = CreateFileMapping_(#INVALID_HANDLE_VALUE, 0, #PAGE_READWRITE | #SEC_COMMIT | #SEC_NOCACHE, 0, Size, Name)
    EndIf
   
    If handle
      *mem = MapViewOfFile_(handle, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
      hMap(Str(*mem)) = handle
      ProcedureReturn *mem
    EndIf   
  EndProcedure
 
  Procedure Open(Name.s)
   
    Protected handle, *mem
   
    handle = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, 0, Name)
    If handle
      *mem = MapViewOfFile_(handle, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
      hMap(Str(*mem)) = handle
      ProcedureReturn *mem
    EndIf
  EndProcedure
 
  Procedure Close(*Mem)
    Protected result
   
    UnmapViewOfFile_(*Mem)
    result = CloseHandle_(hMap(Str(*Mem)))
    DeleteMapElement(hMap(), Str(*Mem))
    ProcedureReturn result
  EndProcedure
 
EndModule
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten