[Linux] Shared Memory

Share your advanced PureBasic knowledge/code with the community.
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

[Linux] Shared Memory

Post by remi_meier »

I've written this out of curiosity and it's far from complete or perhaps
even correctness. In particular, I'm not sure if I've used it correctly
together with fork_(). Actually, I've read somewhere that it isn't even
the best way to do shared memory on Linux.
But anyway, it's a very comfortable way of IPC and very easy to use
instead of multi-threading! So perhaps if somebody could verify the
code, it would certainly have it's use.

Code: Select all

; probably not the best way to do IPC but if you use it correctly
; there shouldn't be a problem
; and even then, I'm not sure, if I've used it correctly together with fork_()



#IPC_CREAT = 01000
#IPC_RMID	 = 0

ImportC ""
  ftok_.i(pathname.p-utf8, proj.b )  As "ftok"
  shmget_.i(key.i, size.i, shmflg.i) As "shmget"
  shmat_.i(shmid.i, *shmaddr, shmflg.i) As "shmat"
  shmctl_.i(shmid.i, cmd.i, *buf) As "shmctl"
  shmdt_.i(*shmaddr) As "shmdt"
;   exit_(status.i) As "exit"
;   wait_.i(*stat) As "wait"
EndImport

; Creates or connects to the shared memory
; file_name: a name for a file to use for Shared Memory
; size: in bytes
; returns -1 if error, else the memory address (and ID)
Procedure.i connect_shared_memory(file_name.s, size.i)
  Protected key.i, shmid.i, *ptr
  Protected code.c = 'R'
  
  key = ftok_(file_name, code)
  If key = -1
    ProcedureReturn -1
  EndIf
  
  shmid = shmget_(key, size, 0644 | #IPC_CREAT)
  If shmid = -1
    ProcedureReturn -1
  EndIf
  
  *ptr = shmat_(shmid, 0, 0)
  If *ptr = -1
    shmctl_(shmid, #IPC_RMID, #Null) ; destroy it
    
    ProcedureReturn -1
  EndIf
  
  ProcedureReturn *ptr
EndProcedure

; returns -1 on error
Procedure.i disconnect_shared_memory(shm_id.i)
  ProcedureReturn shmdt_(shm_id)
EndProcedure

Procedure.i destroy_shared_memory(shm_id)
  ProcedureReturn shmctl_(shm_id, #IPC_RMID, #Null) ; destroy it
EndProcedure









*mem = connect_shared_memory("fork and IPC.pb", 1024)

If *mem <> -1
  Debug "shared memory works :)"
  
  pid = fork_()
  If pid = 0
    ; i'm the child
    PokeS(*mem, "Hi from the child!")
    Debug "child will end now"
    End(0)
  Else
    ; i'm the parent
    
    
    ; wait_(@exit) WHY is this an assembler error??
    Delay(100) ; that's a very unsecure way, but it's just because of the wait_() problem...
    
    MessageRequester("Result:", PeekS(*mem))
  EndIf
  
  
  destroy_shared_memory(*mem)
EndIf
Athlon64 3700+, 1024MB Ram, Radeon X1600