IPC (inter-process communication, interprocess communication) can have three ways of sharing information (along with the file system, with the kernel, with shared memory). (Of course, although it is interprocess communication, it can also be connected with threads).
The relative IPC continuity (persistence of IPC Object) also has three kinds:
-
with process (process-persistent IPC)
IPC object persists until the last owning process is closed. Typical IPC has pipes (pipeline) and FIFOs (FIFO object)
-
Persistent with kernel (kernel-persistent IPC)
The IPC object persists until the kernel is restarted or the object is explicitly closed, and in Unix this object has System V Message Queuing, semaphore, and shared memory. (Note that POSIX Message Queuing, semaphores, and shared memory are required for at least the kernel to persist, but it is also possible for the file to persist, so look at the specific implementation of the system).
-
with file system persistence (filesystem-persistent IPC)
Unless an IPC object is explicitly deleted, Otherwise the IPC object will remain (even if the kernel is restarted). If POSIX Message Queuing, semaphores, and shared memory are all methods of using memory-mapped files, then these IPC have such properties.
The persistence of different UNIX IPC:
With process:
Pipe, FIFO, POSIX mutex (mutex), condition variable (condition variable), Read-write lock (read-write lock), memory-based semaphore (memory-based semaphore), and Fcntl Record lock,tcp and UDP sockets, Unix domain sockets
With kernel:
POSIX message queue (Message Queuing), named Semaphore (named semaphore), System V message queue, semaphore, shared memory.
It is important to note that although the IPC listed above does not follow the filesystem, as we have just said, Posix IPC may be different (with different persistence) depending on the implementation of the system, for example, writing a file is definitely a file system continuity operation, But the IPC is not usually implemented in this way. Very few IPC implementations persist, as this degrades performance and does not conform to the IPC's design intent.
Unix IPC Some are famous, some are nameless, to the specific use of the time to know, if the nameless IPC (typically pipe), must be dependent on the process, but the well-known IPC (typically FIFOs), can be used in two non-dependent processes (dependence can be manifested in, One process is a child of another process).
Posix IPC
POSIX's full name is "portable Operating System Interface", POSIX is not just a single standard, but also an IEEE (Institute for Electrical and Electronics A standard family, as specified by Engineers, Inc. IEEE.
A total of three Posix IPC is message queue (Message Queuing), semaphores (semaphore), shared memory, and in Posix.1, the three IPC naming conventions are:
- Must conform to an existing path name rule (must consist of up to Path_max bytes, including the trailing null character).
- If it starts with a slash, then different calls to these functions will access the same queue, and if it does not start with a slash character, then the effect depends on the implementation
- The interpretation of the extra slash character in the name is defined by the implementation.
Because the rules of the naming system for different distributions of UNIX systems are quite dissimilar, you need to be aware of the naming conventions when using POSIX. To prevent this portability problem, the UNIX system has defined three macros:
S_TPYEISMQ (BUF) S_typeissem (BUF) S_typeisshm (BUF)
The purpose of these three macros is to detect whether the current system has different implementations of the POSIX IPC (message queue, semaphores, shared memory), and BUF is a struct that points to the stat struct (the one that can give Fstat , Lstat, or the buffer structure populated by the stat function). If the current system has a different implementation for a particular IPC, the corresponding macro will return a value other than 0, otherwise it will return 0.
However, these three macros are rarely used because there is no system to guarantee that the three macros corresponding to the POSIX IPC (message queue, semaphores, shared memory) will have different implementations in different systems. For example, in the Solaris2.6 system, these three macros all return 0.
We can use the following function to create a new POSIX IPC name:
Char*px_ipc_name (Const Char*name) { Char*dir, *DST, *Slash; if(DST =malloc(Path_max)) ==NULL) { if(dir = getenv ("Px_ipc_name")) ==NULL) {#ifdef Posix_ipc_prefix dir=Posix_ipc_prefix#elsedir="/tmp/"; }} Slash= (Dir[strlen (dir)-1] =='/') ?"":"/"; snprintf (DST, Path_max,"%s%s%s", dir, Slash, name); returnDST;}
opening and creation of the channel for Posix IPC
Open POSIX three IPC channels its practical is three different functions Mq_open (open message Queue), Sem_open (open semaphore), Shm_open (open shared memory), these three functions can be opened in different ways to create IPC channels, in addition to the most common o_ Rdonly (Read only), O_wronly (write only), O_RDWR (readable and writable), there are four other ways
- o_creat:
Create a nonexistent message channel, semaphore or shared memory IPC, when creating a new message queue, semaphore, or shared memory, their userid is set to the process's valid UserID. Semaphore, the GroupID of shared memory is set to the groupid of the process or the system default GroupID, and the groupid of the message queue is set to the groupid of the process.
- o_excl: When this flag and o_ When creat is used together, only the nonexistent message channel, semaphore, or shared memory IPC can be created, and if the IPC created already exists, creating the function (that is, the three functions) will return a eexist error. (Note that a separate o_excl is meaningless)
- O_nonblock:
This flag allows Message Queuing to read an empty queue or write a full queue.
- o_trunc
about POSIX IPC permissions:
The new message queue, the known semaphore, or the IPC object in the shared memory area, is created by the Mq_open,sem_open or Shm_open function that contains the O/_CREAT flag in the Oflags parameter, which is associated with each object of the IPC type. Just as they are associated with each UNIX file (this is easy to imagine, because Unix is a handy way to map the objects of memory to a file.) )
When the same three functions open an already existing message queue, semaphore or shared memory object (or no o_creat is specified, or o_creat but no specified O_EXCL, and the object already exists), the permission test is performed based on the following information:
- The permission bit given to the IPC object at the time of creation;
- The type of access requested (o/rdonly,o/wronly or O_RDWR);
- The valid user ID of the calling process, the valid group ID, and the individual worker group ID (if the auxiliary group is supported)
Most UNIX cores perform permission tests as follows (if any of the steps below are not met, then none of the following steps are performed and the operation is considered a failure)
- If the current process has a valid user ID of 0 (superuser), then access is allowed
- The valid user ID of the current process is equal to the master ID of the IPC object, if the corresponding user access permission bit has been set, then access is allowed, otherwise access is denied.
The corresponding access permission bit here means: if the current process for read access to open the IPC object, then the user Read permission bit must be set, if the current process for write access to open the IPC object, then the user write permission bit must be set
- The valid group ID of the current process or one of its secondary group IDs equals the group ID of the IPC object, and if the corresponding group access permission bit has been set, access is allowed, otherwise access is denied.
- If the corresponding other user rights bits have been set, then access is allowed, otherwise access is denied.
System V IPC
System V IPC and POSIX IPC are essentially similar in nature, but it is important to note that the System V IPC is not continuous with the process and is continuous with the kernel. The name of the POSIX IPC can be found in the same way as the file system, but the system V IPC can not find the names of them (these IPC).
key_t keys and Ftok Function
System V IPC Systems The three functions that create a new IPC are Msgget (), Senget (), Shmget (), and the parameters of the three functions are (key_t key, int mode), in fact key is a key value created by the Ftok function, The declaration of the Ftok function is:
#include <sys/ipc.h>key_t ftok (constchar *pathname,int id);
This function assumes that the program uses the system V IPC for communication, and the client and server agree to use a meaningful pathname (which is already the path name), if the client and server only use a single channel, then the ID is 1 If the client and server require a two-way channel (and two), you can make one channel ID 1 and the other 2, as long as pathname is the same, it can be considered that the client and server use the same channel to communicate.
Using the Ftok function internal implementation is called the stat function, and then the following behavior (typical implementation, not mandatory, it is important to note that pathname is an existing path):
- Pathname File System Information (St_dev of the STAT structure) (12-bit)
- Pathname The index node number of the corresponding file in this file system (St_ino of the STAT structure) (12-bit)
- The low 8-bit is the ID value (cannot be 0 (8-bit)
The System V IPC does not guarantee that the keys are not the same when different paths, and the ID value must not be 0 (so many implementations define the key value of 0 as Ipc_private).
ipc_perm Structure
In the System V IPC, the kernel maintains an IPC information structure, just like the file information structure: (Note that this structure is somewhat different from the book)
structipc_perm{__key_t __key; /*Key. */__uid_t uid; /*Owner ' s user ID. */__gid_t GID; /*Owner ' s group ID. */__uid_t cuid; /*Creator ' s user ID. */__gid_t Cgid; /*Creator ' s group ID. */unsigned Short intMode/*read/write permission. */unsigned Short int__pad1; unsigned Short int__seq;/*Sequence number. */unsigned Short int__pad2; __syscall_ulong_t __glibc_reserved1; __syscall_ulong_t __glibc_reserved2;};
The usage of the two flags (Ipc_creat, IPC_EXCL) of the system IPC V is essentially the same as that of POSIX, noting that the system IPC v also has a ipc_private flag bit, This flag bit is dedicated to creating independent IPC channels (no combination of pathname and IDs can create Ipc_private).
IPC Permissions
In fact, the permissions of the system V IPC are composed of the above mentioned Ipc_creat, IPC_EXCL and Ipc_private plus read and write permissions, and the read and write permissions are determined by the 6 macros defined by the system Msg_r, Msg_w, Sem_r, Sem_a, Shm_r, Shm_w together, the concrete how to make a look at the following table:
Note ipc_perm structure's cuid, UID creation IPC will be set to the caller's user Id,cgid, GID will be set to the caller's group ID, the only difference is that the creator IDs are not allowed to be changed, But the owner's IDs can be changed by the CTLXXX directive (the CTLXXX directive corresponds to three different IPC has three different functions, these three functions do not use the file mode mask Modify permissions, but set to the corresponding function to specify the exact value)
Each time a process accesses an IPC object, the IPC performs a level two check, which is opened (called the GETXXX function) once and executed once each time the object is used:
- The IPC performs an initial check when each process establishes a channel that accesses an already existing IPC object with a getxxx function. Verify that the caller's Oflag parameter has no access bit specified in the Ipc_perm struct mode member of the object. When any calling process creates an IPC, the function returns an error if its specified oflag corresponding permission bit is forbidden. However, this kind of testing is useless because it assumes that the caller knows the scope of their permission (user, group member, or other user), and the calling process can bypass this check by specifying the Oflag as 0.
- The permission test for each call to the IPC is the same as the POSIX permission check method.
identifier reuse identifier Reuse
ipc_ The perm structure also has a variable named seq, which is a slot usage sequence number, which is a counter maintained by the kernel for each potential IPC object in the system, and the kernel increments the corresponding slot number whenever an IPC object is deleted. If the overflow is a loop of 0 (note that this is just an ordinary SVR4 implementation, UNIX98 does not force the use of this technique, for example, I have no such implementation in Ubuntu 16).
In order to prevent malicious processes from randomly reading the system V IPC to intercept information, the possible values of the IPC identifiers are designed to be very large, and when an IPC table entry is accessed, the obtained IPC value will increase the number of IPC table entries, as in the case of a process:
int I, msqid; for 0 i++) { = Msgget ((key_t) ipc_private, Svmsg_mode | Ipc_creat); printf ("msgid =%d\n", msqid); Msgctl (Msqid, Ipc_rmid, NULL);} return 0;
Output:
IPCs and Ipcrm Programs
Because the three types of System V IPC are not identified by path names in the file system, standard LS and RM programs cannot see them, nor can they be removed, but any system that implements the systems V IPC provides two special programs, IPCS and IPCRM, The IPCS outputs various information about the System V IPC features, Ipcrm deletes a System V message queue, semaphore, or shared memory area.
Kernel Limits
most implementations of the System V IPC have intrinsic kernel limitations, such as the maximum number, which are often small, but can still be modified.
UNIX interprocess Communication (IPC) concept (Posix,system V IPC)