# POSIX Shared-Memory API
IPC有shared memory, message queue, semaphore等等,以下只關注shared memory。
### Creating or opening an IPC object
Each IPC mechanism has an associated open call (mq_open(), sem_open(), or <u>shm_open()</u>), which is analogous to the traditional UNIX open() system call used for files. Given an IPC object name, the IPC open call either:
1. creates a new object with the given name, opens that object, and returns a handle
for it; or
2. opens an existing object and returns a handle for that object.
The handle returned by the IPC open call is analogous to the file descriptor
returned by the traditional open() system call—it is used in subsequent calls to refer to the object.
The type of handle returned by the IPC open call depends on the type of object.
For message queues, it is a message queue descriptor, a value of type mqd_t. For
semaphores, it is a pointer of type sem_t *. For shared memory, it is a file descriptor.
All of the IPC open calls permit at least three arguments—name, oflag, and
mode—as exemplified by the following shm_open() call:
fd = shm_open("/mymem", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
These arguments are analogous to the arguments of the traditional UNIX open()
system call.
註:以下是關於shared memory object。
1. The FD_CLOEXEC flag (see fcntl(2)) is set for the file descriptor.
2. After a call to mmap(2) the file descriptor may be closed without affecting the memory mapping.
3. 剛建立的shared memory object為zero size,使用ftruncate設定shared memory初始大小並會清除成0。
### Closing an IPC object
For POSIX message queues and semaphores, there is an IPC close call that indicates
that the calling process has finished using the object and the system may deallocate
any resources that were associated with the object for this process. <u>A POSIX shared memory object is closed by unmapping it with munmap().</u>
IPC objects are automatically closed if the process terminates or performs an exec().
註(1):message queue和semaphore會等到所有processes執行對應的close call才被kernel close/destroy。
<u>註(2):Shared memory object會等到所有processes執行munmap才自動被kernel close/destroy。</u>
### IPC object permissions
IPC objects have a permissions mask that is the same as for files. Permissions for
accessing an IPC object are similar to those for accessing files, except that execute permission has no meaning for POSIX IPC objects.
Since kernel 2.6.19, Linux supports the use of access control lists (ACLs) for
setting the permissions on POSIX shared memory objects and named semaphores.
### IPC object deletion and object persistence
<u>As with open files, POSIX IPC objects are reference counted—the kernel maintains a
count of the number of open references to the object.</u> By comparison with System V
IPC objects, this makes it easier for applications to determine when the object can
be safely deleted.
Each IPC object has a corresponding unlink call whose operation is analogous
to the traditional unlink() system call for files. <u>The unlink call immediately removes the object’s name, and then destroys the object once all processes cease using it(i.e., when the reference count falls to zero).</u> For message queues and semaphores, this means that the object is destroyed after all processes have closed the object; <u>for shared memory, destruction occurs after all processes have unmapped the object using munmap().</u>
<u>After an object is unlinked, IPC open calls specifying the same object name will
refer to a new object (or fail, if O_CREAT was not specified).</u>
As with System V IPC, POSIX IPC objects have kernel persistence. Once created, an object name continues to exist until it is unlinked or the system is shut down.
This allows a process to create an object, modify its state, and then exit, leaving the object to be accessed by some process that is started at a later time.
<u>The operation of shm_unlink() is analogous to unlink(2): it
removes a shared memory object name, and, once all processes have
unmapped the object, deallocates and destroys the contents of the
associated memory region. After a successful shm_unlink(),
attempts to shm_open() an object with the same name fail (unless
O_CREAT was specified, in which case a new, distinct object is
created).</u>
<u>註:拿Shared memory object來說好了,shared memory object name和shared memory object會是兩個獨立的資料結構,在第一次執行shm_open並設定O_CREAT flag時,會將給定的shared memory object name和所建立出的shared memory object所關聯起來(shared memory name所對應的指標指向share memory object資料結構),當每次由process執行mmap時,此shared memory object的reference count(由kernel maintain)會加1,相對地,當每次由process執行munmap時,此shared memory object的reference count(由kernel maintain)會減1,而執行unlink時,其實質意義是斷開此shared memory object name和shared memory object之間的關聯,並刪除此shared memory object name,而此shared memory object name即不存在,沒有任何process可以在以這個shared memory object name來open shared memory,因為這已經是一個不存在的shared memory object name,往後可以再用此shared memory object name去建立新的shared memory object,但注意到剛剛的unlink動作並不影響原本shared memory object本身,只是讓shared memory object失去了name,此時shared memory object也許還是處於由多個processes shared的狀態,每當有一個process執行mummap,shared memory object的reference count會減1直到減少至0,此shared memory object會被kernel destroy。</u>
### Additional information
The POSIX shared memory object implementation on Linux makes use of a dedicated tmpfs filesystem that is normally mounted under /dev/shm.
註:在linux中的shared memory其實是被對應到tmpfs,此tmpfs被mounted在/dev/shm此directory下, 預設的可用的shared memory大小約為實體記憶體的一半(可以先用free -h查看實體記憶體大小再用df -h看到/dev/shm上的tmpfs),如果目前沒使用到任何shared memory的話,/dev/shm是不佔空間的,而每當使用shm_open來建立一個shared memory object的同時,會在/dev/shm/下建立對應的檔案。
### Reference
1. Linux manual page
2. The Linux Programming Interface-Michael Kerrisk