千家信息网

Linux如何实现进程间共享内存

发表于:2024-09-24 作者:千家信息网编辑
千家信息网最后更新 2024年09月24日,这篇文章主要介绍"Linux如何实现进程间共享内存",在日常操作中,相信很多人在Linux如何实现进程间共享内存问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Linux
千家信息网最后更新 2024年09月24日Linux如何实现进程间共享内存

这篇文章主要介绍"Linux如何实现进程间共享内存",在日常操作中,相信很多人在Linux如何实现进程间共享内存问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Linux如何实现进程间共享内存"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

共享内存就是允许两个或多个进程共享一定的存储区。就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。因为数据不需要在客户机和服务器端之间复制,数据直接写到内存,不用若干次数据拷贝,所以这是最快的一种IPC。

共享内存 IPC 原理

共享内存进程间通信机制主要用于实现进程间大量的数据传输,下图所示为进程间使用共享内存实现大量数据传输的示意图:

共享内存是在内存中单独开辟的一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限、大小和最近访问的时间等。该数据结构定义如下:

from /usr/include/linux/shm.hstruct shmid_ds {struct ipc_perm shm_perm; /* operation perms 操作权限 */int shm_segsz; /* size of segment (bytes) 段长度大小 */__kernel_time_t shm_atime; /* last attach time 最近attach时间 */__kernel_time_t shm_dtime; /* last detach time 最近detach时间 */__kernel_time_t shm_ctime; /* last change time 最近change时间 */__kernel_ipc_pid_t shm_cpid; /* pid of creator 创建者pid */__kernel_ipc_pid_t shm_lpid; /* pid of last operator 最近操作pid */unsigned short shm_nattch; /* no. of current attaches */unsigned short shm_unused; /* compatibility */void *shm_unused2; /* ditto - used by DIPC */void *shm_unused3; /* unused */};

两个进程在使用此共享内存空间之前,需要在进程地址空间与共享内存空间之间建立联系,即将共享内存空间挂载到进程中。

系统对共享内存做了以下限制:

#define SHMMAX 0x2000000 /* max shared seg size (bytes) 最大共享段大小 */#define SHMMIN 1 /* min shared seg size (bytes) 最小共享段大小 */#define SHMMNI 4096 /* max num of segs system wide */#define SHMALL (SHMMAX/getpagesize()*(SHMMNI/16))#define SHMSEG SHMMNI /* max shared segs per process */

Linux 共享内存管理

1.创建共享内存
#include  #include

/* * 第一个参数为 key 值,一般由 ftok() 函数产生 * 第二个参数为欲创建的共享内存段大小(单位为字节) * 第三个参数用来标识共享内存段的创建标识 */

int shmget(key_t key, size_t size, int shmflg);
2.共享内存控制
#include  #include

/* * 第一个参数为要操作的共享内存标识符 * 第二个参数为要执行的操作 * 第三个参数为 shmid_ds 结构的临时共享内存变量信息 */

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
3.映射共享内存对象

系统调用 shmat() 函数实现将一个共享内存段映射到调用进程的数据段中,并返回内存空间首地址,其函数声明如下:

#include #include

/* * 第一个参数为要操作的共享内存标识符 * 第二个参数用来指定共享内存的映射地址,非0则为此参数,为0的话由系统分配 * 第三个参数用来指定共享内存段的访问权限和映射条件 */

void *shmat(int shmid, const void *shmaddr, int shmflg);
4.分离共享内存对象

在使用完毕共享内存空间后,需要使用 shmdt() 函数调用将其与当前进程分离。函数声明如下:

#include #include

/* * 参数为分配的共享内存首地址 */

int shmdt(const void *shmaddr);
共享内存在父子进程间遵循的约定

1.使用 fork() 函数创建一个子进程后,该进程继承父亲进程挂载的共享内存。

2.如果调用 exec() 执行一个新的程序,则所有挂载的共享内存将被自动卸载。

3.如果在某个进程中调用了 exit() 函数,所有挂载的共享内存将与当前进程脱离关系。

程序实例

申请一段共享内存,父进程在首地址处存入一整数,子进程读出。

#include#include #include #include #include#include#define SHM_SIZE 1024int main(){int shm_id, pid;int *ptr = NULL;

/* 申请共享内存 */

shm_id = shmget((key_t)1004, SHM_SIZE, IPC_CREAT | 0600);

/* 映射共享内存到进程地址空间 */

ptr = (int*)shmat(shm_id, 0, 0);printf("Attach addr is %p \n", ptr);*ptr = 1004;printf("The Value of Parent is : %d \n", *ptr);if((pid=fork()) == -1){perror("fork Err");exit(0);}else if(!pid){printf("The Value of Child is : %d \n", *ptr);exit(0);}else{sleep(1);

/* 解除映射 */

shmdt(ptr);

/* 删除共享内存 */

shmctl(shm_id, IPC_RMID, 0);}return 0;}

输出结果:

到此,关于"Linux如何实现进程间共享内存"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

内存 进程 参数 空间 函数 数据 地址 大小 时间 标识 学习 三个 权限 系统 结构 两个 之间 对象 数据传输 数据结构 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 松江区品牌软件开发报价表 河北特色软件开发诚信合作 计算机网络安全研究现状 软件开发车联网物联网未来规划 DW连接数据库登录系统验证码 计算机网络技术中差错的概念 厉害的网络安全公司 校园网络安全 数据库表单追加大量数据 qq实时传文件会不会存在服务器 福建网络安全员考试题库 数据库技术专项 网络安全知识读本赛 武威市网络安全宣传周金融日 和龙软件开发公司电话 网络技术网站设计专业 进行数据库表设置的类型有哪些 dota2 全球服务器 摩纹网络技术有限公司 数据库技术及应用自学考试 公安内部网络安全新闻 备案的域名服务器换了怎么办 服务器购买咨询谷歌15 法国网络安全节 网络安全攻击相关的场景 新洲区电商网络安全维护收费标准 企业网络安全防护图片 操作系统与网络技术 青岛加加互联网络科技有限公司 新一代网络技术设计
0