linux IPC---共享内存
来源:互联网 发布:高性能网络编程1 编辑:程序博客网 时间:2024/06/05 23:44
共享内存
共享内存是允许两个或多个进程共享同一块内存区域,因为进程可以直接读写内存,不需要任何数据的拷贝,这是一种最快的进程间通信方式。共享内存是多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。当然,多个进程同时访问共享区就得需要一些同步机制,如信号量或互斥锁等,这些以后再记录,本文先讲最简单的共享内存使用方式。
linux共享内存操作的四个函数
shmget函数:创建一个共享内存对象并返回共享内存标识符。
shmat函数:把创建的共享内存映射到具体的进程空间去,映射后就可以在本进程使用这块地址。
shmctl函数:共享内存管理,完成对共享内存的控制。
shmdt函数:撤销映射共享内存,但是并不删除所指定的共享内存区,而只是将先前用shmat函数连接好的共享内存脱离目前的进程。
shmget 函数
#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>int shmget(key_t key,int size,int shmflg)
返回值:若成功,返回共享内存段标识符;若出错,返回-1
参数说明:
- Key:IPC_PRIVATE (为0,比较常见的一种)
- Size:共享内存区大小
- Shmflg:同 open 函数的权限位,也可以用八进制表示法
shmat函数
#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>char *shmat(int shmid,const void *shmaddr,int shmflg)
返回值:若成功,返回被映射的段地址;若出错,返回-1
参数说明:
- shmid:要映射的共享内存区标识符
- shmaddr:将共享内存映射到指定位置(若为 0 则表示把该段共享内存映射到调用进程的地址空间)
- Shmflg
- SHM_RDONLY:共享内存只读
- 默认 0:共享内存可读写
shmctl函数
#include <sys/types.h>#include <sys/shm.h>int shmctl(int shmid, int cmd, struct shmid_ds *buf)
返回值:若成功,返回0;若出错,返回-1
参数含义:
- shmid:共享内存标识符
cmd:
- IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中
- IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内
- IPC_RMID:删除这片共享内存
buf:共享内存管理shmid_ds结构体。
以下是 shmid_ds 结构:
struct shmid_ds { struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ pid_t shm_lpid; /* pid of last shmop() operation */ pid_t shm_cpid; /* pid of creator */ shmatt_t shm_nattch; /* number of current attaches */ time_t shm_atime; /* last-attach time */ time_t shm_dtime; /* last-detach time */ time_t shm_ctime; /* last-change time */ };
shmdt函数
#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>int shmdt(const void *shmaddr)
返回值:若成功,返回0;若出错,返回-1
参数说明:
- Shmaddr:被映射的共享内存段地址
示例程序
/* share_memory.c*/#include <unistd.h> #include <stdio.h> #include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <sys/shm.h>#define BUFF 1024int main () { int shmid; pid_t pid; char *shmaddr;//共享内存地址 /*创建共享内存*/ if((shmid=shmget(IPC_PRIVATE,BUFF,0666))<0) { perror("shmget"); exit(-1); } else printf("Create shared memory,id = %d\n",shmid); if ((pid = fork()) < 0) { perror("fork"); exit(-1); } else if (pid == 0) //子进程 { /*映射共享内存*/ if((shmaddr=shmat(shmid,0,0))<(char *)0) { perror("shmat"); exit(-1); } else printf("I am child,shmat shared memory success\n"); //子进程往共享内存写数据 strcpy( shmaddr, "from child process\n"); //snprintf(shmaddr, 13, "%012d", 12345); //本函数调用并不删除所指定的共享内存区,而只是将先前用shmat函数连接(attach)好的共享内存脱离(detach)目前的进程 shmdt(shmaddr); return 0; } else //父进程 { //保证子进程已经往共享内存写入数据了 sleep(2); /*映射共享内存*/ if((shmaddr=shmat(shmid,0,0))<(char *)0) { perror("shmat"); exit(-1); } else printf("I am parent,shmat shared memory success\n"); //读取共享内存的数据 printf("read from share memory: %s",shmaddr); shmdt(shmaddr); //等待子进程退出 waitpid(pid,NULL,0); exit(0); } return 0; }
实验结果:
ubuntu:~/test/process_test$ ./share_memoryCreate shared memory,id = 0I am child,shmat shared memory successI am parent,shmat shared memory successread from share memory: from child process
以上程序,我们调用shmget函数创建共享内存区,然后调用fork函数创建子进程,在子进程中调用shmat映射共享内存地址,然后往共享内存区写数据。在父进程中,同样调用shmat函数映射共享内存区,然后从共享内存区读取子进程写入的数据。
共享内存的简单应用就说到这了,下次讲消息队列。
阅读全文
0 0
- linux IPC---共享内存
- linux ipc机制-共享内存
- Linux IPC之共享内存
- Linux IPC之共享内存
- Linux-IPC之共享内存
- Linux IPC之共享内存
- Linux IPC实 --共享内存/内存映射
- Linux下IPC共享内存通信
- Linux XSI IPC 之共享内存
- linux SysV IPC shm共享内存实现
- Unix/Linux下的IPC---共享内存
- Linux中IPC机制:共享内存区
- Linux 进程间通信 (IPC) //共享内存
- linux最快的IPC--共享内存
- Linux ipc------System V共享内存
- Linux ipc------ 信号量+共享内存编程
- Linux IPC实践(10) --Posix共享内存
- Linux共享内存,打印系统IPC信息
- Java集合---HashMap源码剖析
- Ecilpse上运行SVN报找不到SVNConnector最有效解决方法
- 经典java题
- rbtree原理及应用--前世今生及性质
- webupload文件上传过程中遇到的一个问题
- linux IPC---共享内存
- Java集合---HashSet的源码分析
- 使用Eclipse从SVN检出Maven项目
- Android多点触控实现图片缩放预览
- socket网络协议
- BZOJ2243
- Java集合---ConcurrentHashMap原理
- 删除表中重复数据
- maven 笔记