An analysis of the Linux process IPC [interprocess communication SYSTEMV Shared Memory]
- Shared Memory Concepts, overview
- Related functions for shared memory
Shared memory Concepts, overview:
A shared memory area is a portion of physical memory that is shared by multiple processes
Multiple processes can map the shared memory to their own virtual memory space , all user-space processes to operate shared memory, to map it to their own virtual memory space, through the mapped virtual memory space address to operate shared memory, so as to achieve inter-process data communication
Shared memory is the quickest way to share data between processes, where a process writes data to a shared memory region, and all processes that share that memory area can immediately see what's in it
The synchronization mechanism is not provided by itself and can be synchronized by the semaphore (notification with semaphore)
Improved data processing efficiency, one of the most efficient IPC mechanisms
Property information for Shared memory:
struct shmid_ds{ struct ipc_perm shm_perm; size_t shm_segsz; //共享内存大小 pid_t shm_lpid; //最后一次调用系统调用的进程的pid pid_t shm_cpid; //创建者pid shmatt_t shm_nattch;//当前成功映射的进程的数量 time_t shm_atime; //最后一个成功映射的时间 time_t shm_dtime; //最后一个解除映射的时间 time_t shm_ctime; //最后一次改变的时间 ....;}
Steps to use shared memory:
使用shmget函数创建共享内存使用shmat函数映射共享内存,将这段创建的共享内存映射到具体的进程虚拟内存空间中
Create shared memory
#include<sys/shm.h>int shmget(key_t key,size_t size,int shmflg);返回:如果成功,返回内核中共享内存的表示ID,如果失败,则返回-1参数:key:用户制定的共享内存键值size_t:共享内存的大小shmflg:IPC_CREAT,IPC_EXCL等权限errno: EINVAL(无效的内存段) EEXIST(内存段已经存在,无法创建) EIDRM(内存段已经被删除) ENOENT(内存段不存在) EACCES(权限不够) ENOMEN(没有足够的内存来创建内存段)
Control of shared Memory:
#include<sys/shm.h>int shmctl(int shmid,int cmd,struct shmid_ds *buf);返回:成功返回0,出错返回-1参数: shmid:共享内存ID buf:共享内存属性指针cmd: IPC_STAT 获取共享内存段属性 IPC_SET 设置共享内存段属性 IPC_RMID 删除共享内存段 SHM_LOCK 锁定共享内存段页面 SHM_UNLOCK 解除共享内存段页面的锁定
The mapping of shared memory and the release of mappings:
#include<sys/shm.h>void* shmat(int shmid,char *shmaddr,int shmflag);返回:成功返回共享内存映射到进程虚拟内存空间中的地址,失败返回-1,然后通过操作共享内存的地址来进行写操作int shmdt(char *shmaddr);返回:如果失败,返回-1参数: shmid:共享内存ID shmaddr:映射到进程虚拟内存空间的地址,建议设置为0,由系统分配 shmflg:若shmaddr设置为0,则shmflag也设置为0 SHM_RND SHMLBA 地址为2的乘方 SHM_RDONLY 只读方式链接 errno EINVAL 无效的IPC ID值或者无效的地址 ENOMEN 没有足够内存 EACCESS 权限不够 子进程不继承父进程创建的共享内存,大家是共享的,子进程继承父进程映射的地址
The following code is in the form of a pipeline to synchronize the shared memory, a process implementation of the shared memory after the write, through the pipeline to notify another process to read from the shared memory:
/* * =========================================================================== * * filename:tell.h * DESC Ription: * version:1.0 * created:2017 April 16 10:40 31 seconds * Revision:none * COMPILER:GCC * Author: (), * Company: * * ========================================================================= == */#ifndef __tell_h_#define __tell_h_//Initialize pipelineextern voidPipe_init ();//Notification pipelineextern voidPipe_notify ();//Pipeline blocking waitextern voidPipe_wait ();//destruction of pipelinesextern voidPipe_destory ();#endif
/* * =========================================================================== * * FILENAME:TELL.C * DESC Ription: * version:1.0 * created:2017 April 16 10:42 23 seconds * Revision:none * COMPILER:GCC * Author: (), * Company: * * ========================================================================= == */#include <stdio.h>#include <stdlib.h>#include "tell.h"#include <unistd.h>#define BUFFER_SIZE 1024x768//Pipe file description symbolStatic intpipe_fd[2];//Initialize pipelineextern voidPipe_init () {if(Pipe (PIPE_FD) <0) {perror ("Create pipe error\n"); }}//Pipeline waitingextern voidPipe_wait () {CharBuffer[buffer_size];if(Read (pipe_fd[0],&buffer,sizeof(buffer))) !=0){printf("Read content:%s\n", buffer); }}//Notification pipelineextern voidPipe_notify () {ssize_t size;CharContent[] ="Notify";if(size = Write (pipe_fd[1],content,sizeof(content))) !=sizeof(content)) {Perror ("Write error"); }}//destruction of pipelinesextern voidPipe_destory () {Close (pipe_fd[0]); Close (pipe_fd[1]);}
/ * * =========================================================================== * * filename:shmtest.c * D Escription: * version:1.0 * created:2017 April 16 10:51 54 seconds * Revision:none * compiler:g CC * Author: (), * Company: * * ====================================================================== ===== */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include "tell.h"#include <sys/shm.h>#define SHM_BUFFER_SIZE 1024x768intMainintargcChar*argv[]) {pid_t pid;intShmid;//Create shared memoryShmid = Shmget (Ipc_private,shm_buffer_size,ipc_creat | Ipc_excl |0777);if(Shmid <0) {perror ("Create share memory Error"); }//Initialize pipelinePipe_init ();if(PID = fork ()) <0){ }Else if(PID >0){//time slice for parent process Execution //parent process mapping of shared memory int* Shm_int_pointer = Shmat (Shmid,0,0);if(Shm_int_pointer = = (int*)-1) {perror ("Error"); }//Parent process writes data to shared memory*shm_int_pointer =Ten; * (Shm_int_pointer +1)= -; * (Shm_int_pointer +2) = +;//de-mapping shared memorySHMDT (Shm_int_pointer);//Notify child processPipe_notify ();//Pipelines for destructionPipe_destory (); Wait0); }Else{//Sub-Process Execution time slice //Sub-process blockingPipe_wait ();int*shm_int_pointer = Shmat (Shmid,0,0);if(Shm_int_pointer = = (int*)-1) {perror ("Error");Exit(1); }intNUM1 = *shm_int_pointer;intnum2 = * (shm_int_pointer+1);intnum3 = * (shm_int_pointer+2);printf("num1:%d,num2:%d,num3:%d\n", num1,num2,num3); SHMDT (Shm_int_pointer);//delete shared memory intShm_ctl_result = Shmctl (shmid,ipc_rmid,null);if(Shm_ctl_result = =-1) {perror ("Delete shmctl error"); } pipe_destory (); }return 0;}
The above section is a simple call about the shared memory part, the code has been debugged
Welcome to the blog for continuous visits
An analysis of the Linux process IPC [interprocess communication SYSTEMV Shared Memory]