linux进程通信共享内存原理是什么
发表于:2025-02-06 作者:千家信息网编辑
千家信息网最后更新 2025年02月06日,本篇内容主要讲解"linux进程通信共享内存原理是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"linux进程通信共享内存原理是什么"吧!1 有一个全
千家信息网最后更新 2025年02月06日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安全错误
数据库的锁怎样保障安全
网络安全审计日志设备
陕西省网络安全法
致远电子软件开发怎么样
数据库技术实验7
河南计算机网络技术专业
抚顺新零售软件开发公司
数据库更新存在的问题
服务器 监控系统
数据库查询工具官方绿色版
软件开发过程模型示例
mc服务器无法连接
北京特色软件开发技巧
潮州数据链软件开发优化价格
网络板块股票网络安全板块个股
南通软件开发工资标准
网络安全就业培训学校
闵行区散射网络技术结构设计
福建通讯软件开发设施应用
集合数据库
驻场软件开发报价
数据库实时产生随机数
证明软件开发的正确性
sdk数据库
游戏软件开发面试题
带硬防服务器弊端
was应用程序服务器在哪找
嵌入式软件转行应用软件开发
网络安全演练标语
税务软件开发工资
n卡服务器无法连接