- 进程替换
使用 man exec 查看其不同的函数类型。
主要有四种:
execl()execlp()execv() execvp()
(以上四种除了参数不一样,其他都一样,只是处理的场景不同)
上面四个均为库函数,最终陷入内核调用的execve() - fork() + execv 是创建新进程的方式。
由于替换的是当前的进程,因此不会返回值,因为当前进程是其父进程拷贝出来的,只是替换了它的实体部分(替换函数调用成功,该进程就变成了一个新的进程,会从头重新执行(其内部整个代码段都会被替换))
示例:以ps替换当前程序为例
char path 新替换程序的路径
char*arg, 传给新程序主函数的第一个参数,一般为程序的名字(可修改)
arg后面是剩余的参数列表,参数给属是可变的,因此以空指针作为最后一个参数。
charenvp[] 存放传给新的主程序的环境变量
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4
5 int main(int argc,char*argv[],char*envp[])
6 {
7 printf("man pid=%d\n",getpid());
8 char *myargv[] = {"ps","-f",0);
9 execve("/usr/bin/ps",myargv,envp);
10
11
12
13
14
15
16
17
18
19 printf("exec erro");
20 exit(0);
21 }
22
- 什么情况下,才会发生内存泄露?
当一个进程正在执行的过程中,我们申请的堆空间使用完以后,没有进行释放。会发生泄露,因为系统无法回收这个进程。(使用的空间是记录在页表中,并且同页表可以查找到使用(进程)页面的 情况。 - 内存 = 物理内存 + 虚拟内存 (当因为物理内存不够挤出来的进程,在不需要的时候是不会调回来的)【申请的空间的上限是操作系统允许的最大值,防止恶意申请)
说白了就是,假设实际的物理内存有2G,除去内核等占用的空间,操作系统允许用户申请的安全内存大小,若申请2G,肯定是不通过的,但是如果加上虚拟内存,实际的内存就达到4G,允许的申请的内存空间也就变大了,因此就可以申请成功。
【内核区,用户区(栈,堆,代码,数据)都需要占用空间】
1,当一个进程申请内存资源的时候,剩余物理内存 > 申请的内存
2,若物理内存不够,则需要 剩余物理+剩余虚拟 > 申请的内存