linux进程通信共享内存原理是什么
发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,本篇内容主要讲解"linux进程通信共享内存原理是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"linux进程通信共享内存原理是什么"吧!1 有一个全
千家信息网最后更新 2026年11月04日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安全错误
数据库的锁怎样保障安全
咖啡
广东猪兼强互联网科技有限公司
今日互联网科技
金融科技还是互联网
科技类互联网
金融科技创新监管互联网金融
互联网金融科技创新
一五八零互联网科技
成都玖崟互联网科技有限公司乐商圈怎么样
江苏南京365互联网科技
北京华百购互联网科技有限公司
互联网金融科技公司干啥的
开一家科技互联网公司需要多少钱
明优互联网科技有限公司
山东星卡互联网科技有限公司官网
小米互联网科技园入驻
富国互联网科技002692
上海创道互联网络科技有限公司
互联网科技接地气
长沙易易互联网科技有限公司
精品咖啡豆
西安互联网科技
互联网与未来科技
互联网科技的英文
友谊互联网络科技
互联网时代科技改变生活
知域互联网科技有限公司大骗子
国大互联网教育科技有限公司薪资
互联网科技股为什么大涨
盐城市攀科互联网科技有限公司