Common ways of Linux IPC
Writing Linux Server-side programs will inevitably involve inter-process communication IPC. Communication is bound to accompany the synchronization mechanism, the following are some common communication and synchronization mechanisms:
- interprocess communication: Anonymous pipes, Named pipes, Message Queuing, shared memory,,
Domain Socket
本机 TCP Socket
files
- Inter-process synchronization: signal, signal volume
- Inter-thread synchronization: Conditional variables, mutexes, read and write locks, spin locks, Barrier.
For most of the business scenario, it's 本机 TCP Socket
enough, and now Linux is 本机 TCP Socket
doing a good job of optimizing it. And if you need to sub-machine deployment process Later, then the program does not need to change, very convenient. As for Domain sockets, the application is also very extensive, you can read this article: UNIX Domain socket IPC.
Principle of shared memory IPC
The biggest advantage of using shared memory for IPC means is the most efficient , the disadvantage is that other synchronization mechanisms are needed .
Shared memory The rationale for IPC is also simple: mapping the same piece of physical memory to the virtual address space of multiple processes, the process virtual address layout can look at this: the Linux virtual address space layout. Linux <sys/shm.h>
provides an interface for related operations:
- Gets
key
the shared memory object that is used to create or obtain an existing;
- Association
attach
, associated to the virtual address space of the current process;
- Separation
detach
, separated from the current process;
- Control such as: Set parameters, lock, release, etc.;
Detailed function interface descriptions can be seen: Linux interprocess communication-Using shared memory
Shared Memory IPC Example
The following demo is a read, a write, IPC uses shared memory, synchronization with the simplest condition variable mates. The final implementation reads the standard input in one process, and the other processes output to the console.
You can use ipcs -m
the view system to use the shared Memory IPC resource list.
Common Header files:
/* file: shm_comm.h */#ifndef _SHM_COMM_H#define _SHM_COMM_H#define MY_SHM_KEY 0x12#define READ_SHM 1#define WRITE_SHM -1typedefstruct { int flag; char buff[1020];}__attribute__((packed)) S_SHM_BUF; // 单字节对齐,方便 ipcs -m 查看对比大小#endif
Read process
/ * FILE:SHM_READ.C * /#include <stdio.h>#include <string.h>#include <sys/shm.h>#include <unistd.h>#include <stdlib.h>#include "shm_comm.h"intMain () {void*SHM = NULL; S_shm_buf *shbuf;intRET =0;intShmid =0;/ * Request shared memory by key, get ID * /Shmid = Shmget (My_shm_key,sizeof(S_SHM_BUF), ipc_creat);if(-1= = Shmid) {printf("Get share memory failed!\n");Exit(exit_failure); }/ * Attach shared memory to the process address space based on ID, get the first address * /SHM = Shmat (Shmid,0,0);if(-1L== (Long) {SHM) {printf("Share memory attach failed!\n"); }printf("Share memory attached at%p\n", SHM); Shbuf = (s_shm_buf*) SHM; while(1) {if(Read_shm = = Shbuf->flag) {printf("read:%s\n", Shbuf->buff); Shbuf->flag = WRITE_SHM;if(0==strncmp(Shbuf->buff,"End",3)) { Break; } }Else{Sleep (1); } }/ * Detach the shared memory from the process space according to the first address * /ret = SHMDT (SHM);if(-1= = ret) {printf("Share memory detach failed!\n");Exit(exit_failure); }/ * Let the operating system delete the shared memory based on the ID * /ret = Shmctl (Shmid, Ipc_rmid,0);if(-1= = ret) {printf("Share memory remove failed!\n");Exit(exit_failure); }printf("program End ok!\n");return 0;}
Write process
/ * FILE:SHM_WRITE.C * /#include <stdio.h>#include <string.h>#include <sys/shm.h>#include <unistd.h>#include <stdlib.h>#include "shm_comm.h"intMain () {void*SHM = NULL; S_shm_buf *shbuf;intRET =0;intShmid =0; Shmid = Shmget (My_shm_key,sizeof(S_SHM_BUF), ipc_creat);if(-1= = Shmid) {printf("Get share memory failed!\n");Exit(exit_failure); } SHM = Shmat (Shmid,0,0);if(-1L== (Long) {SHM) {printf("Share memory attach failed!\n"); }printf("Share memory attached at%p\n", SHM); Shbuf = (s_shm_buf*) SHM;memset(Shbuf,0,sizeof(*SHBUF)); Shbuf->flag = WRITE_SHM; while(1) {if(Write_shm = = Shbuf->flag) {printf("Write:");scanf('%s ', Shbuf->buff); Shbuf->flag = READ_SHM;if(0==strncmp(Shbuf->buff,"End",3)) { Break; } }Else{Sleep (1); }} ret = SHMDT (SHM);if(-1= = ret) {printf("Share memory detach failed!\n");Exit(exit_failure); }printf("program End ok!\n");return 0;}
Makefile
# MakefileCFLAGS = -Wall -Werror -g -m64compile$(CC)$(CFLAGS) $^ -o [email protected].PHONY : allall : shm_read.bin shm_write.bin# 注意 makefile 的缩进要用<TAB>shm_read.bin : shm_read.c shm_comm.h $(compile)shm_write.bin : shm_write.c shm_comm.h $(compile).PHONY : cleanclean: rm *.bin
Linux IPC Shared Memory usage