Page 1 of 1

Shared Memory

Posted: Sat Sep 29, 2012 4:43 am
by RichAlgeni
Thanks to Mistrel & Siggi Rings for their code. I used it as a base to understand how to write a shared memory process. There are two programs, a producer and a consumer. The producer creates the shared memory, and the consumer is able to read it.

Code: Select all

; shm_producer.pb

EnableExplicit

Procedure.i CreateMap(*MapName, Size.i)

    Protected hFileMap.i
    Protected *MapView.i
    Protected Security.SECURITY_ATTRIBUTES

    hFileMap = CreateFileMapping_(-1, 0, #PAGE_READWRITE, 0, Size, *MapName)
    ProcedureReturn hFileMap

EndProcedure

Procedure.s GetMapString(*MapName)

    Protected hFileMap.i
    Protected *MapView
    Protected Value.s

    hFileMap = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, 0, *MapName)
    If hFileMap
        *MapView = MapViewOfFile_(hFileMap, #FILE_MAP_WRITE, 0, 0, 0)

;/ Read the map value to the file then Unmap the mapped view of the file from memory

        If *MapView
            Value = PeekS(*MapView)
            UnmapViewOfFile_(*MapView)
        Else
            Value = ""
        EndIf
        CloseHandle_(hFileMap)
    Else
        Value = ""
    EndIf

    ProcedureReturn Value

EndProcedure

Procedure.i SetMapString(*MapName, *Value)

    Protected hFileMap.i
    Protected *MapView
    Protected Value.s    = PeekS(*Value)
    Protected retValue.i = #False

    hFileMap = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, 0, *MapName)
    If hFileMap
        *MapView = MapViewOfFile_(hFileMap, #FILE_MAP_WRITE, 0, 0, 0)

;/ Write the map value to the file, then Unmap the mapped view of the file from memory

        If *MapView
            PokeS(*MapView, Value)
            UnmapViewOfFile_(*MapView)
            retValue = #True
        EndIf
        CloseHandle_(hFileMap)
    EndIf

    ProcedureReturn retValue

EndProcedure

Procedure.i CloseMapPtr(*MapPtr)

    Protected Value.i

;/ Unmap the mapped view of the file from memory

    If UnmapViewOfFile_(*MapPtr)
        Value = #True
    Else
        Value = #False
    EndIf

    ProcedureReturn Value

EndProcedure

Procedure CloseMap(hMap)

    Protected Value.i

    If CloseHandle_(hMap)
        Value = #True
    Else
        Value = #False
    EndIf

    ProcedureReturn Value

EndProcedure

Define hMap.i
Define *MapView
Define MapName.s = "SharedMapName"
Define sendStr.s = ""
Define mapSize.i = 512

hMap = CreateMap(@MapName, mapSize)

;/ Output from source

OpenConsole()

sendStr = "First string to be sent..., start consumer process"
SetMapString(@MapName, @sendStr)
PrintN("Set Map = " + GetMapString(@MapName))

Repeat

    PrintN("")
    Print("Enter text To send, or press <enter> to quit: ")
    sendStr = Input()

    If sendStr <> ""
        SetMapString(@MapName, @sendStr)
        PrintN("Set Map = " + GetMapString(@MapName))
    Else
        Break
    EndIf

ForEver
    
CloseMapPtr(*MapView)
CloseMap(hMap)

CloseConsole()

End

Code: Select all

; shm_consumer.pb

EnableExplicit

Procedure.i GetMapPtr(*MapName)

    Protected hFileMap.i
    Protected *MapView
    Protected Value.i = #False

    hFileMap = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, 0, *MapName)

    If hFileMap
        *MapView = MapViewOfFile_(hFileMap, #FILE_MAP_WRITE, 0, 0, 0)

        If *MapView
            Value = *MapView
        EndIf

        CloseHandle_(hFileMap)
    EndIf

    ProcedureReturn Value

EndProcedure

Define *MapView
Define MapName.s  = "SharedMapName"
Define sentText.s = ""

;/ Output from source

OpenConsole()

;/ Output from other process

Repeat

    *MapView = GetMapPtr(@MapName)
    If *MapView > 0
        sentText = PeekS(*MapView)
        If sentText <> ""
            PrintN("Read Map = " + sentText)
            PrintN("")
            PrintN("Press <enter> to check shared memory")
            Input()
        Else
            Break
        EndIf
    Else
        Break
    EndIf

ForEver

CloseConsole()

End
Switch between the two, you'll see how they work.

Question for those who may know: Can there be a possibility of IMA's if a read is done while data is being written to the shared memory? Has anyone handled such a situation?

Rich

Re: Shared Memory

Posted: Sat Sep 29, 2012 9:41 pm
by idle
thanks good tip.

No you shouldn't get an IMA
See here for details on file mapping
http://msdn.microsoft.com/en-us/library ... s.85).aspx

Re: Shared Memory

Posted: Tue Oct 02, 2012 9:09 pm
by RichAlgeni
Idle, can you repost your link? It's broken.

Re: Shared Memory

Posted: Tue Oct 02, 2012 9:11 pm
by luis
If you hover on it you can see the part missing and rebuild it:

Code: Select all

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366556(v=vs.85).aspx

Re: Shared Memory

Posted: Tue Oct 02, 2012 9:17 pm
by RichAlgeni
Thanks Luis!

Re: Shared Memory

Posted: Tue Oct 02, 2012 10:14 pm
by Nico
RichAlgeni,

Your code is welcome but it is not a novelty, code similar have already been posted (Original code coded by me in 2004), already eight years ago, here:
http://www.purebasic.fr/english/viewtop ... ViewOfFile

Re: Shared Memory

Posted: Tue Oct 02, 2012 11:21 pm
by RichAlgeni
Then thanks to Nico too!

It was never my intent to claim credit for anyone else's code. It's just that it helps me better understand it when I deconstruct it, then build it back up as I might do it.

Rich

Re: Shared Memory

Posted: Wed Oct 03, 2012 11:53 am
by Nico
No problem :)