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)
.
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
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