linux进程通信共享内存原理是什么
发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,本篇内容主要讲解"linux进程通信共享内存原理是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"linux进程通信共享内存原理是什么"吧!1 有一个全
千家信息网最后更新 2025年12月03日linux进程通信共享内存原理是什么
本篇内容主要讲解"linux进程通信共享内存原理是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"linux进程通信共享内存原理是什么"吧!
1 有一个全局的结构体数据,每次需要一块共享的内存时(shmget),从里面取一个结构体,记录相关的信息。
struct shmid_ds {
// 权限相关
struct ipc_perm shm_perm; /* operation perms */
// 共享内存的大小
int shm_segsz; /* size of segment (bytes) */
time_t shm_atime; /* last attach time */
time_t shm_dtime; /* last detach time */
time_t shm_ctime; /* last change time */
// 创建该结构体的进程
unsigned short shm_cpid; /* pid of creator */
unsigned short shm_lpid; /* pid of last operator */
// 当前使用该共享内存的进程数
short shm_nattch; /* no. of current attaches */
/* the following are private */
// 共享内存的页数
unsigned short shm_npages; /* size of segment (pages) */
// 指向共享的物理内存的指针
unsigned long *shm_pages; /* array of ptrs to frames -> SHMMAX */
// 使用该共享内存的进程信息
struct vm_area_struct *attaches; /* descriptors for attaches */
}
2 调用shmat的时候传入shmget返回的id。shmat根据id找到对应的shmid_ds 结构体。新建一个vm_area_struct结构体。开始地址和结束地址根据shmid_ds 中的信息计算,也就是用户申请的大小。接着把vm_area_struct插入进程中管理vm_area_struct的avl树。并且把一些上下文信息保存到页表项。缺页中断的时候在shm_swap_in里使用。
shm_sgn = shmd->vm_pte + ((shmd->vm_offset >> PAGE_SHIFT) << SHM_IDX_SHIFT);
for (tmp = shmd->vm_start; tmp < shmd->vm_end; tmp += PAGE_SIZE,
shm_sgn += (1 << SHM_IDX_SHIFT)) {
page_dir = pgd_offset(shmd->vm_task,tmp);
page_middle = pmd_alloc(page_dir,tmp);
if (!page_middle)
return -ENOMEM;
page_table = pte_alloc(page_middle,tmp);
if (!page_table)
return -ENOMEM;
pte_val(*page_table) = shm_sgn;
}
3 进程访问共享内存范围中的地址时,触发缺页中断。
void do_no_page(struct vm_area_struct * vma, unsigned long address,
int write_access)
{
pte_t * page_table;
pte_t entry;
unsigned long page;
// 在进程页表里获取address对应的页表项地址
page_table = get_empty_pgtable(vma->vm_task,address);
// 分配失败则返回
if (!page_table)
return;
entry = *page_table;
// 已经建立了虚拟地址到物理地址的映射,返回
if (pte_present(entry))
return;
// 还没有建立映射
if (!pte_none(entry)) {
do_swap_page(vma, address, page_table, entry, write_access);
return;
}
......
}
在缺页中断中调用do_swap_page。
static inline void do_swap_page(struct vm_area_struct * vma, unsigned long address,
pte_t * page_table, pte_t entry, int write_access)
{
pte_t page;
if (!vma->vm_ops || !vma->vm_ops->swapin) {
swap_in(vma, page_table, pte_val(entry), write_access);
return;
}
page = vma->vm_ops->swapin(vma, address - vma->vm_start + vma->vm_offset, pte_val(entry));
if (pte_val(*page_table) != pte_val(entry)) {
free_page(pte_page(page));
return;
}
if (mem_map[MAP_NR(pte_page(page))] > 1 && !(vma->vm_flags & VM_SHARED))
page = pte_wrprotect(page);
++vma->vm_task->mm->rss;
++vma->vm_task->mm->maj_flt;
// 写入物理地址
*page_table = page;
return;
}
其中vma->vm_ops->swapin对应shm.c的shm_swap_in
pte_val(pte) = shp->shm_pages[idx];
// 还没有分配物理内存
if (!pte_present(pte)) {
// 分配物理内存
unsigned long page = get_free_page(GFP_KERNEL);
...
// 记录物理地址
shp->shm_pages[idx] = pte_val(pte);
}
mem_map[MAP_NR(pte_page(pte))]++;
return pte_modify(pte, shmd->vm_page_prot);
如果还没分配物理地址则分配,否则直接范围已经分配的地址。do_swap_page函数的最后一句会把物理地址写入进程的页表项。下次就不会缺页中断了。
同理,其他进程共享该块内存的时候,如果访问范围内的地址,处理过程是类似的。进程访问某一个地址,发生缺页中断,然后进入do_swap_page函数处理,再到shm_swap_in。发现这时候共享内存已经映射了物理地址。最后改写自己的页表项。因为各个进程都对应同一块内存,所以操作的时候会互相感知,实现通信。
到此,相信大家对"linux进程通信共享内存原理是什么"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
内存
地址
进程
物理
分配
结构
通信
信息
时候
原理
范围
内容
函数
大小
处理
学习
实用
更深
上下
上下文
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
提高网络安全判别能力
图数据库实现oneid
珠海金融软件开发定制
三大数据库都没上的期刊
资阳网络技术服务价格
Tsr服务器
上海有机化学数据库红外标准谱图
360对网络安全检测
疫情网络安全危机
nr数据库解压多大
万应互联网科技有限公司
iis不能打开数据库
安卓手机安装mqtt服务器
宿舍管理系统需要哪些数据库
无线网络技术支撑中心
二合一控制服务器
互联网科技创新方面的工作总结
自学云计算软件开发
软件开发有哪些课件
sql查数据库倒数
提高网络安全判别能力
数据库关系模式是谁先提出的
三大数据库都没上的期刊
h3c网络技术
北京志翔软件开发公司
数据库 substr
计算机网络技术专业要多少分
12306数据库架构
联通国家网络安全宣传
华为云服务器如何确保信息的安全