Inter-process communication refers to the Process Communication and information exchange between multiple processes. Linux IPC is basically inherited from the UNIX platform. It mainly includes the original Unix IPC, System v ipc, and socket-based IPC. In addition, Linux also supports posix ipc.
System V, BSD, POSIX
System V is one of the earliest commercial releases of UNIX operating systems. It was initially developed by at&t (American Telephone & Telegraph) and was first released in 1983. System V has released four major versions, of which svr4 (System V Release 4) is the most successful version. BSD (Berkeley Software Distribution, also known as Berkeley UNIX) was developed by the University of California between 1977 and 1995. Between 1880s and 1990s, System V and BSD represent two major Unix operating styles. Their main differences are as follows:
System V BSD
Root script location/etc/init. d/etc/rc. d/
Default shell bshell cshell
File System Data/etc/mnttab/etc/mtab
Kernel location/Unix/vmunix
Printer device LP RLP
String function memcopy bcopy
Terminal initialization setting file/etc/initab/etc/TTYs
Terminal Control termio termios
The operating style of a Linux system is usually between the two.
POSIX (Portable Operating System Interface [for Unix]) is developed by IEEE (Institute of Electrical and Electronics Engineers, Institute of electronic and electrical engineering. Most of the existing UNIX systems follow the POSIX standard, while Linux has followed the POSIX standard from the very beginning.
The original Unix IPC
1. Signal
Signals are events generated under certain conditions in Unix/Linux systems. A signal is an asynchronous communication mechanism. A process does not need to perform any operations to wait for the signal to arrive. When an event occurs in the process of receiving the signal asynchronously, the operating system will interrupt the execution of the Process receiving the signal and then execute the corresponding signal processing program.
(1) register the signal processing function
# Include <signal. h>
/* Typedef void (* sighandler_t) (INT); sighandler_t signal (int signum, sighandler_t handler );*/
* Void (* signal (int signum, void (* Handler) (INT); // sig_ign & sig_dfl
* Int sigaction (int signum, const struct sigaction * Act, struct sigaction * oldact );
(2) sending signals
# Include <signal. h>
* Int kill (pid_t PID, int sig); // # include <sys/types. h>
* Int raise (INT sig); // kill (getpid (), sig );
* Unsigned int alarm (unsigned int seconds); // (# include <unistd. h>) sends a sigalrm signal to the process itself after seconds.
(3) Signal Set
Signal Set is defined as: typedef struct {unsigned long sig [_ nsig_words];} sigset_t;
* Int sigaddset (sigset_t * Set, int sig );
* Int sigemptyset (sigset_t * Set );
2. Pipeline (PIPE)
Pipelines are used to connect data streams between different processes.
(1) The simplest way to transmit data between two programs is to use the popen () and pclose () functions:
# Include <stdio. h>
File * popen (const char * command, const char * open_mode );
Int pclose (File * stream );
The popen () function first calls a shell, and thenCommandPass it as a parameter to shell. In this way, two processes must be started every time you call the popen () function. However, in Linux, all parameter extensions (parameter expansion) are executed by shell.CommandAll parameter extensions inCommandThe program is completed before it starts.
(2) pipe () function:
# Include <unistd. h>
Int pipe (INT pipefd [2]);
The popen () function can return only one media transcoding Descriptor and a file stream. You can use the fread () and fwrite () functions to access the media transcoding. The pipe () function returns two pipeline descriptors:Pipefd [0]AndPipefd [1], Any writePipefd [1]Data can be retrieved fromPipefd [0]The pipe () function returns the file descriptor, which can only be accessed by the underlying read () and write () system calls. The pipe () function is usually used to implement communication between parent and child processes.
(3) named pipe: FIFO
# Include <sys/types. h>
# Include <sys/STAT. h>
Int mkfifo (const char * 1_o_name, mode_t mode );
The first two pipelines can only be used between related programs. Using Named pipelines can solve this problem. When open () is used to enable FIFO, the mode cannot contain o_rdwr. The most common mode is the combination of o_rdonly, o_wronly, and o_nonblock. O_nonblock affects the execution of read () and write () on the FIFO.
PS: To view library function usage, the most reliable information is from Linux manual page:
$ Sudo apt-Get install manpages-Dev
$ MAN 3Function_name
System V IPC
System v ipc refers to three inter-process communication tools introduced by at&t in the system V.2 release: (1) semaphores used to manage access to shared resources (2) shared memory, it is used to efficiently implement data sharing between processes (3) message queue, and used to transmit data between processes. These three tools are collectively referred to as the System v ipc object. Each object has a unique IPC identifier (identifier ). To ensure that different processes can obtain the same IPC object, an IPC key must be provided. The kernel is responsible for converting the IPC keyword into an IPC identifier.
System v ipc has similar syntax. The general operation is as follows:
(1) If you select the IPC keyword, you can use the following three methods:
A) ipc_private. The kernel selects a keyword, generates an IPC object, and passes the IPC identifier directly to another process.
B) Directly select a keyword.
C) use the ftok () function to generate a keyword.
(2) Use the semget ()/shmget ()/msgget () function to create or access the IPC object based on the IPC keyword key and a flag. If the key is ipc_private, or the key is not associated with an existing IPC object and the flag contains the ipc_creat flag, a new IPC object is created.
(3) Use the semctl ()/shmctl ()/msgctl () function to modify the attributes of the IPC object.
(4) use the semctl ()/shmctl ()/msgctl () function and ipc_rmid to destroy the IPC instance.
System v ipc sets an ipc_perm struct for each IPC object and initializes it when creating the IPC object. This struct defines the access permission and owner of the IPC object:
Struct ipc_perm {
Uid_t uid; // user ID of the owner
Gid_t GID; // The Group ID of the owner
Uid_t cuid; // user ID of the Creator
Gid_t cgid; // The Group ID of the Creator
Mode_t mode; // Access Mode
...
};
Commands for managing IPC objects in shell are IPCS, ipcmk, and ipcrm.
1. semaphores)
The semaphore set of System V represents a set of one or more semaphores. The kernel maintains a semid_ds data structure for each semaphores set, and each semaphores in the semaphores set are represented by an unknown struct, which contains at least the following members:
Struct {
Unsigned short semval; // signal value, always greater than or equal to 0
Pid_t sempid; // PID of the last operation
...
};
# Include <sys/types. h>
# Include <sys/IPC. h>
# Include <sys/SEM. h>
(1) Create or access semaphores
* Int semget (key_t key, int nsems, int flag );
Nsems specifies the number of semaphores in the semaphores set. If you only obtain the semaphores Set Identifier (rather than the new one), nsems can be 0. The lower 9 bits of the flag are used as the semaphore access limit, similar to the file access permission. If both ipc_creat and ipc_excl are specified in the flag, if the key is already associated with an existing IPC object, the function returns an eexist error. For example, the flag can be ipc_creat | 0666.
(2) control the semaphore set
* Int semctl (INT Semid, int semnum, int cmd, Union semun Arg );
Run the CMD operation on the Semid semaphores set. The two common values of CMD are: setval, which initializes the semnum semaphores, Arg. Val, and ipc_rmid, which deletes semaphores.
(3) operate on one or more semaphores
* Int semop (INT Semid, struct sembuf * SOPs, unsigned nsops );
* Struct sembuf {
Unsigned short sem_num; // semaphore Index
Short sem_op; // The operation on semaphores. The two common values are-1 and + 1, which respectively represent the P and V Operations.
Short sem_flag; // the important value is sem_undo: when the process ends, the corresponding operation will be canceled; at the same time, if the process ends without releasing resources, the system will automatically release
};
2. Shared Memory
Shared memory allows two or more processes to share a certain storage zone. Because data does not need to be copied, this is the fastest IPC.
# Include <sys/IPC. h>
# Include <sys/SHM. h>
(1) Create or access Shared Memory
* Int shmget (key_t key, size_t size, int shmflg );
(2) append the shared memory to the address space of the process
* Void * shmat (INT shmid, const void * shmaddr, int shmflg); // shmaddr is usually null, and the system selects an additional address for shared memory. shmflg can be shm_rdonly
(3) Separate the shared memory from the address space of the process
* Int shmdt (const void * shmaddr); // shmaddr is the return value of the shmat () function.
(4) control the shared memory
* Int shmctl (INT shmid, int cmd, struct shmid_ds * BUF );
* Struct shmid_ds {
Struct ipc_perm shm_perm;
...
};
The common values of CMD are as follows: (a) obtain the shmid_ds structure of the current shared memory from ipc_stat and save it in Buf (2) set the shmid_ds structure of the current shared memory using the value in Buf (3) ipc_rmid: Delete the current shared memory
3. Message Queue
The message queue is stored in the kernel and is a linked list composed of messages.
# Include <sys/types. h>
# Include <sys/IPC. h>
# Include <sys/msg. h>
(1) Create or access a Message Queue
* Int msgget (key_t key, int msgflg );
(2) operate message queues
* Int msgsnd (INT msqid, const void * MSG, size_t nbytes, int msgflg );
The struct to which MSG points must start with a long int member. It is the message type of msgrcv () and must be greater than 0. Nbytes refers to the size of the MSG pointing to the struct, but does not include the size of the long int part.
* Ssize_t msgrcv (INT msqid, void * MSG, size_t nbytes, long msgtype, int msgflg );
If msgtype is 0, the first message in the message queue is returned; if it is a positive integer, the first message of this type in the queue is returned; if it is a negative number, returns the first message with the minimum value in the queue, and the minimum value must be less than or equal to the absolute value of msgtype.
(3) Control Message Queues
* Int msgctl (INT msqid, int cmd, struct msqid_ds * BUF );
* Struct msqid_ds {
Struct ipc_perm msg_perm;
...
};
Socket
Socket is a connection-based IPC introduced by Berkeley in the BSD system. It is an abstraction of network interfaces (hardware) and network protocols (software. It not only solves the problem that an unknown pipeline can only communicate among relevant processes in one way, but also solves the problem that different hosts on the network cannot communicate with each other.
The socket has three attributes: domain, type, and protocol, which correspond to different domains. The socket also has an address as its name.
Domain specifies the protocol family used for socket communication. The most common domain is af_inet, which indicates the network socket. The underlying protocol is the IP protocol. For Network sockets, because the server may provide multiple services, the client must use the IP port number to specify specific services. Af_unix represents a local socket, which is implemented in a Unix/Linux File System.
The IP protocol provides two communication methods: streaming and datagram rams. The corresponding socket types are streaming sockets and datagram sockets. Streaming socket (sock_stream) is used to provide connection-oriented and reliable data transmission services. This Service ensures that data can be sent without errors or duplicates and received in order. Streaming sockets use the TCP protocol. The datagram socket (sock_dgram) provides a connectionless service. This service does not guarantee the reliability of data transmission. data may be lost or duplicated during transmission, and data may not be received sequentially. The datagram socket uses the UDP protocol.
One type of socket may be implemented using more than one Protocol. The Protocol attribute of the socket is used to specify a specific protocol.
Summary:
System V IPC API
1. Message Queue
Int ftok (const char * pathname, int prj_id );
Int msgget (key_t key, int msgflag );
Int msgsnd (INT msqid, const void * msgp, size_t msgsz, int msgflg );
Int msgrcv (INT msqid, void * msgp, size_t msgsz, long msgtyp, int msgflg );
2. semaphores
Int semget (key_t key, int nsems, int semflag );
Int semctl (INT Semid, int semnum, int cmd ,...);
Int semop (INT Semid, struct sembuf * SOPs, unsigned nsops, struct timespec * timeout );
3. Shared Memory
Int shmget (key_t key, size_t size, int shmflag );
Int shmctl (INT shmid, int cmd, struct shmid_ds * BUF );
POSIX IPC API