Next: , Previous: , Up: posix   [Index]


4.23 Shared memory

The POSIX shared memory API allow processes to communicate informations by sharing a region of memory.

NOTE On GNU+Linux systems, for an introduction to the API we must refer to the manual page shm_overview(7).

Function: shm-open name oflag mode

Interface to the C function shm_open(), see the manual page shm_open(3). Open, and optionally create, a shared memory object and return a file descriptor referencing it. If successful return a fixnum representing the file descriptor, else raise an exception.

name must be the pathname representing the shared memory object. oflag must be the bitwise inclusive OR combination of some of the following values:

O_RDONLY                O_RDWR
O_CREAT                 O_EXCL
O_TRUNC

mode must be the bitwise inclusive OR combination of some of the following values:

S_IRUSR   S_IWUSR   S_IXUSR
S_IRGRP   S_IWGRP   S_IXGRP
S_IROTH   S_IWOTH   S_IXOTH
Function: shm-unlink name

Interface to the C function shm_unlink(), see the manual page shm_unlink(3). Remove the shared memory object selected by the pathname name. If successful return unspecified values, else raise an exception.

The following example shows how two processes can exchange a signed integer; notice how the only information shared at the beginning is the pathname of the shared memory object and the dimension of the mapped memory. Also notice that the correct way of synchronising two processes for shared memory access is with POSIX semaphores, posix sem for details.

#!r6rs
(import (vicare)
  (prefix (vicare posix) px.)
  (vicare platform constants)
  (only (vicare language-extensions syntaxes)
        unwind-protect
        callet)

(define shm.pathname
  "/vicare-posix-shm.test")
(define shm.dim
  (px.sysconf _SC_PAGESIZE))

(define (parent child-pid)
  (let ((shm.fd (callet px.shm-open shm.pathname
                        (oflags (fxior O_CREAT O_RDWR))
                        (mode   (fxior S_IRUSR S_IWUSR)))))
    (px.ftruncate shm.fd shm.dim)
    (unwind-protect
        (unwind-protect
            (let ((shm.base (callet px.mmap
                              (address #f)
                              (size    shm.dim)
                              (prot    (fxior PROT_READ
                                              PROT_WRITE))
                              (flags   MAP_SHARED)
                              (fd      shm.fd)
                              (offset  0))))
              (unwind-protect
                  (begin
                    (px.waitpid child-pid 0)
                    (pointer-ref-c-signed-int shm.base 0))
                (px.munmap shm.base shm.dim)))
          (px.close shm.fd))
      (px.shm-unlink shm.pathname))))

(define (child)
  ;; Give the parent some time to create and open the
  ;; shared memory object.
  (px.nanosleep 1 0)
  (let ((shm.fd (callet px.shm-open shm.pathname
                        (oflags (fxior O_CREAT O_RDWR))
                        (mode   (fxior S_IRUSR S_IWUSR)))))
    (unwind-protect
        (let ((shm.base (callet px.mmap
                          (address #f)
                          (size    shm.dim)
                          (prot    (fxior PROT_READ
                                          PROT_WRITE))
                          (flags   MAP_SHARED)
                          (fd      shm.fd)
                          (offset  0))))
          (unwind-protect
              (pointer-set-c-signed-int! shm.base 0 123)
            (px.munmap shm.base shm.dim)))
      (px.close shm.fd)))
  (exit 0))

(px.fork parent child)
⇒ 123

Next: , Previous: , Up: posix   [Index]