C语言如何获得变量的物理地址以及简单的写时拷贝测试
来源:互联网 发布:r创建数据集 dataframe 编辑:程序博客网 时间:2024/06/06 01:44
基本的思路:linux下的/proc/self是对自身进程映射的文件夹,里面的pagemap允许查看到每个虚拟页映射到的物理页。
#include <stdio.h>#include <unistd.h>#include <inttypes.h>intptr_t Mytop(uintptr_t vaddr) { FILE *pagemap; intptr_t paddr = 0; int offset = (vaddr / sysconf(_SC_PAGESIZE)) * sizeof(uint64_t); uint64_t e; // https://www.kernel.org/doc/Documentation/vm/pagemap.txt if ((pagemap = fopen("/proc/self/pagemap", "r"))) { if (lseek(fileno(pagemap), offset, SEEK_SET) == offset) { if (fread(&e, sizeof(uint64_t), 1, pagemap)) { if (e & (1ULL << 63)) { // page present ? paddr = e & ((1ULL << 54) - 1); // pfn mask paddr = paddr * sysconf(_SC_PAGESIZE); // add offset within page paddr = paddr | (vaddr & (sysconf(_SC_PAGESIZE) - 1)); } } } fclose(pagemap); } return paddr;} void TestShow(void *x){ printf("Virtual Address:%u Physical Address:%u\n",x,Mytop((uintptr_t)x));}void main()<pre>{ int a; TestShow(&a);}
呃。。。。顺便一提吧,本人后来测试了一下vfork的写时拷贝,大名鼎鼎的写时拷贝….
结果发现
vfork写时拷贝是完全不存在的。。。。父子进程完全共享虚拟空间,并且经过测试,本人发现了调动vfork后,一定是子进程先结束后父进程才能继续执行!
呃,后来我想了一下,估计原因是这样的: 假设父进程不在子进程调度完成后才能继续玩下跑,那么在父子进程交替着调度往下跑,并且是在同一个堆栈上进行函数调用,栈帧开辟释放,那么结果无疑是一种噩梦般的结果..我有点困扰为什么系统要这么做,于是我去查阅了一下关于vfork的介绍。得到了以下东西:
1. fork要拷贝父进程的数据段;而vfork则不需要完全拷贝父进程的数据段,在子进程没有调用exec和exit之前,子进程与父进程共享数据段
2. fork不对父子进程的执行次序进行任何限制;而在vfork调用中,子进程先运行,父进程挂起,直到子进程调用了exec或exit之后,父子进程的执行次序才不再有限制
顿时有点茅塞顿开的感觉,原来linux内核设计vfork就是和exec配套使用的,写时拷贝更多的是讲一个进程调用vfork确实完全共享进程绝大部分资源,这里是讲共享部分,至于拷贝部分不是说什么蛋疼的程序员,,,比如我。。。无聊的修改了一下局部变量或者是栈上数据,那么系统就要因此给你分配出相应的东西出拷贝一份原有东西再进行你的修改操作,让进程看起来好像是在你(程序员 )写入后系统自动拷贝再去修改。。。。这个是不可能的,内核不可能这么蛋疼专门去检测这些东西,或者说vfork就是为了exec而诞生的,估计内核设计者是这样想的吧,调动vfork的都是极度渴望进行快速exec的程序员同学。所谓的写时拷贝不是说程序员修改栈上数据引发内核专门分配对应资源再进行修改,而是讲的是frok以后调动exec,内核复制相应资源再进行修改!!!
呃。。。。废话有点多,既然测试了vfork发现学习了这么多东西,那么让我们继续进行测试frok吧。。。代码不用贴了吧..
改变点有两个:
1.fork替换了vfork
2.去掉了x = 10;y=20;
结果是发现fork在没有任何修改,父子进程栈上数据就已经是完全不一样了…..
也就是说:fork以后父子进程拥有的函数调用栈不是同一个的!!而vfork则是同一个!!
呃。。。。然后我觉得有必然去测试一下全部变量或者是其他的……过一段时间再更新吧!!
备注:顺手看到,顺手粘贴的东西
_exit不清除IO缓存~~也就是说IO缓冲区的东西是不会输出的~
- C语言如何获得变量的物理地址以及简单的写时拷贝测试
- 【C语言】String类的写时拷贝
- Linux内核---62.用户空间获得变量的物理地址
- string的深浅拷贝以及写时拷贝问题
- 深浅拷贝与写时拷贝的简单认知
- Big-Endian和Little-Endian的判断,以及我写的C语言测试程序
- C语言指针变量的简单使用
- C语言写的简单病毒程序
- 自己写的C语言简单万年历
- c语言写的简单Windows窗口
- C++::浅拷贝,深拷贝,引用计数的拷贝,写时拷贝
- 【C语言简单说】六:取模运算符以及变量的扩展
- C语言 获得系统时间以及时间函数的用法。
- 【C语言】【unix c】如何获得进程自己的PID
- 如何使用C语言实现copy拷贝的功能
- 【C++】浅拷贝和深拷贝以及怎样实现一个简单的string类!!!
- C语言中如何写一个简单可移植而又足够随机的随机数生成器
- C语言外部变量的使用以及erxtern的用法
- Django学习笔记(一)
- STM32启动文件
- iOS界面约束第三方框架对比
- 获取网络文本查看器--HTML源码
- 树状数组
- C语言如何获得变量的物理地址以及简单的写时拷贝测试
- relation "public.***" contains more than "max_fsm_pages" pages with useful free space
- Spring的AOP详解
- 详解HttpURLConnection
- 深入浅出RxJava(二:操作符)
- Linux内存中的Cache真的能被回收吗?
- bzoj 3626 LCA
- 隐私政策
- 建造者模式的实现