Seite 2 von 2

Verfasst: 23.02.2009 15:51
von STARGÅTE
Danke für die Info ...

Damit kann ich dann schon mal eine "mögliche Fehlerquelle" ausschließen...

Verfasst: 24.02.2009 17:36
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 =)

Re: SharedMemory

Verfasst: 20.06.2013 16:05
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

Re: SharedMemory

Verfasst: 20.06.2013 16:43
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

Re: SharedMemory

Verfasst: 20.06.2013 18:48
von ts-soft
Funktioniert wie es soll :wink:
Erst Sender starten, dann Client, dann Messagebox Client schliessen und dann Messagebox Sender schliessen.

Gruß
Thomas

Re: SharedMemory

Verfasst: 20.06.2013 19:15
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.

Re: SharedMemory

Verfasst: 20.06.2013 19:17
von ts-soft
*mem\quit ist mit oder ohne Deiner zugefügten Zeile erstmal 0, sehe das Problem also nicht.

Re: SharedMemory

Verfasst: 24.06.2015 09:55
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:

Re: SharedMemory

Verfasst: 04.09.2015 18:20
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