本章学习内容
1.fork与系统文件结合
2.进程替换(exec),返回值及相关参数
3.malloc申请空间物理内存与虚拟内存结合
一、fork与系统文件结合
前边已经单独讲过fork与系统文件调用,但当fork与系统文件调用相结合时会产生两种情况
情况1:如果先fork后打开文件,父子进程不共享偏移量(pos);
这里我们通过代码观察
main函数代码
运行结果:
从运行结果我们可以看出, a.txt中存储的内容为abcde,我们通过main函数先复制进程后打开文件各输出两次父子进程内容,发现父子进程替输出的内容相同,偏移量没有被父子进程共享,所以父子进程都输出文件的前两个元素。
情况2: 先打开文件后fork,父子进程共享偏移量
main函数代码
运行结果:
这里我们能看到,a.txt中存储的内容为abcde,我们通过main函数先打开文件后复制进程各输出两次父子进程内容,发现父进程先输出首元素,子进程紧接着输出下一个元素,父子进程交替输出,偏移量被父子进程共享,向下一个偏移,所以导致父子进程交替顺序输出文件元素。
二、进程替换(exec)
1.进程替换过程
进程替换后,原程序占用的内存空间全部释放,换成替换程序的内存空间,但PCB不变(id号不变,name修改为新程序的name)
2.进程替换的返回值
进程替换执行成功后无返回值
3.exec系列替换进程方法
库函数(excel、execlp、execle、elecv、elecvp):
int excel( const char* path, const char* arg,…,(char*)NULL);//最后一个参数必须是空指针,代表参数已传完
int execlp( const char* file, const char* arg,…,(char*)NULL);
int excele( const char* path, const char* arg,…,(char*)NULL) char* const ergv[]);
int execv( const char* path, char* const argv[]);
int execvp( const char* file, char* const argv[]);
系统调用(execve):
int execve( const char* path, char* const argv[], char* const envy[]);
代码演示exec系类函数
上述代码中exec系列函数 都是将进程main函数占用的内存空间全部释放,换成ps程序的内存空间,但main函数的PCB保存(进程号保留)
程序运行结果
通过结果我们可以得到原本main函数的pid号为2273通过替换后ps的pid号变为2273,所以说ps替换了main这个进程
三、malloc申请空间物理内存与虚拟内存结合
1.在研究该问题前我们首先要知道
(1)什么是物理内存,什么是虚拟内存
(2)malloc申请的空间在系统哪个区域
(1)物理内存:计算机中实际存在的硬件内存,是计算机中最快的存储器,内存的大小是固定的,其运算速度非常快,常用于存储正在运行的程序 数据 操作系统等信息
虚拟内存:虚拟内存是操作系统对物理内存的扩展机制,它使用硬盘空间来模拟物理内存,以扩展可用的内存空间。内存的大小是可变的,取决于操作系统的配置和需要。虚拟内存的访问速度相对较慢,因为它需要与磁盘进行交互。在物理内存不足时,操作系统可以将部分程序数据移动到虚拟内存中,从而扩展可用内存,但会导致性能下降。
(2)malloc申请的空间在堆区
2.malloc申请空间的理解
进程执行过程中:malloc申请空间不使用时,没有free就会出现内存泄漏。进程结束后,所有向操作系统申请的内存都会被释放。
3.malloc申请1G空间能否成功?(malloc申请空间不能大于堆区空间)
(1)如果剩余的物理内存空间 大于1G,可以申请成功
(2)如果剩的余物理内存空间 小于1G,但存在虚拟内存,且物理内存+虚拟内存空间 大于1G,可以申请成功
(3)如果malloc申请的空间大于堆区空间,即使物理内存+虚拟内存空间足够,也会失败