进程替换和malloc

一、进程替换方式:

1>使用exec系列库函数

#include <unistd.h>

extern char **environ;

int execl(const char *pathname, const char *arg, .../* (char  *) NULL */);
int execlp(const char *file, const char *arg, .../* (char  *) NULL */);
int execle(const char *pathname, const char *arg, .../*, (char *) NULL, char *const envp[]*/);
int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);

2>使用系统调用execve

#include <unistd.h>

int execve(const char *pathname, char *const argv[],char *const envp[]);

execl系列库函数(execl , execlp , execve , execv , execvp )底层还是调用 execve系统调用,这6个本质上没有区别

二、进程替换 

main进程被ps替换之后就消失了,装载ps进程,PCB中的pid,ppid不会发生改变,name会改为替换进程的名称

fork()复制 + exec()替换是系统创建新进程的方式

 1)execl

函数原型:int execl(const char *pathname, const char *arg, .../* (char  *) NULL */);

参数:

pathname:路径+名称,要替换的进程

arg:进程的参数,任何程序执行后主函数第一个参数都是当前程序的名称

(char*)NULL*:规定已NULL(char*)0结束

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 
  5 int main()
  6 {
  7     printf("main pid =%d\n",getpid());
  8     execl("/usr/bin/ps","ps","-f",(char*)0);//将当前进程替换为ps -f,替换之后,原来
    的程序就直接消失了,就没了,直接执行新的进程
  9     printf("execl err\n");
 10  
 11     exit(0);
 12  
 13 }

 #include<stdio.h>
 #include<stdlib.h>
 #include<unistd.h>
 
 int main()
 {
     printf("main pid =%d\n",getpid());
     execl("/usr/bin/ps","abc","-f",(char*)0);//第一个参数为程序的名称,后面的参数>    为指令,名称可以错,但指令不能错,错了就无法解析成功
     printf("execl err\n");
 
     exit(0);

}

名称传错了不影响程序的执行,但路径万万不可传错

 2)execlp

函数原型:int execlp(const char *file, const char *arg, .../* (char  *) NULL */);

参数:

execlp(p指的是环境变量)

 file文件名称会自动在环境变量PATH路径去寻找

arg: 参数

(char*)NULL*:规定已NULL(char*)0结束

 #include<stdio.h>
 #include<stdlib.h>
 #include<unistd.h>
 
 int main()
 {
     printf("main pid =%d\n",getpid());
     execlp("ps","ps","-f",(char*)0);//与execl区别就在于不用传路径
     //execl("/usr/bin/ps","ps","-f",(char*)0);
     printf("execl err\n");
 
     exit(0);
}

execlp与execl区别就在于不用传路径

3)execle

函数原型:int execle(const char *pathname, const char *arg, .../*, (char *) NULL, char *const envp[]*/);

char *const envp[]* :要求传入环境变量

execl和execlp不需要传环境变量,系统默认给,如果想自己改变环境变量,就需要使用execle

 #include<stdio.h>
 #include<stdlib.h>
 #include<unistd.h>

 int main(int argc,char* argv[],char *envp[])
 {
     printf("main pid =%d\n",getpid());
     execle("/usr/bin/ps","ps","-f",(char*)0,envp);//需要传入环境变量
     // execlp("ps","ps","-f",(char*)0);
     //execl("/usr/bin/ps","ps","-f",(char*)0);
     printf("execl err\n");

     exit(0);
 }


                                                                             

 变量前加$ ,就可以打变量的值

 打印环境变量

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(int argc,char* argv[],char* envp[])
{
    int i=0;
    printf("argc=%d\n",argc);

    for(;i<argc;i++)
    {   
        printf("argv[%d]=%s\n",i,argv[i]);
    }   
     for(i=0;envp[i] !=NULL;i++)//打印环境变量
      {
         printf("envp[%d]=%s\n",i,envp[i]);
     }   
     exit(0);
 }   

                                                                  
                                                                  

环境变量下标从0开始,总共53个环境变量

 自己添加环境变量

export 变量名  可以将普通变量变为环境变量

eg:  export MYSTR ,将普通变量MYSTR变为环境变量

 环境变量总数变为54个,下标为30的环境变量就是刚刚我们添加的环境变量。

 4)execv

函数原型: int execv(const char *pathname, char *const argv[]);

 execv与前几个相比,变化在于将参数放在了数组里

 #include<stdio.h>
 #include<stdlib.h>
 #include<unistd.h>

 int main(int argc,char* argv[],char *envp[])
 {
     printf("main pid =%d\n",getpid());
     char *myargv[] = {"ps","-f",0};//参数放在数组里,以0结尾
     execv("/usr/bin/ps",myargv);
     // execle("/usr/bin/ps","ps","-f",(char*)0,envp);    
     // execlp("ps","ps","-f",(char*)0);
     //execl("/usr/bin/ps","ps","-f",(char*)0);
     printf("execl err\n");
     
     exit(0);
 }
 
                                                                       
                                                                       
                                                                       
                                                                       

5)execvp

函数原型int execvp(const char *file, char *const argv[]);

文件名,参数放在数组里

 #include<stdio.h>
 #include<stdlib.h>
 #include<unistd.h>

 int main(int argc,char* argv[],char *envp[])
 {
     printf("main pid =%d\n",getpid());
     char *myargv[] = {"ps","-f",0};//参数放在数组里,以0结尾
     execvp("ps",myargv);
     // execv("/usr/bin/ps",myargv);
     // execle("/usr/bin/ps","ps","-f",(char*)0,envp);    
     // execlp("ps","ps","-f",(char*)0);
     //execl("/usr/bin/ps","ps","-f",(char*)0);
     printf("execl err\n");
     
     exit(0);
 }
 
                                                                        

 6)execve

函数原型:int execve(const char *pathname, char *const argv[],char *const envp[]);

execve是系统调用上述几个库函数底层都是使用系统调用execve

 #include<stdio.h>
 #include<stdlib.h>
 #include<unistd.h>

 int main(int argc,char* argv[],char *envp[])
 {
     printf("main pid =%d\n",getpid());
     char *myargv[] = {"ps","-f",0};//参数放在数组里,以0结尾
     execve("/usr/bin/ps",myargv,envp);
     // execvp("ps",myargv);
     // execv("/usr/bin/ps",myargv);
     // execle("/usr/bin/ps","ps","-f",(char*)0,envp);    
     // execlp("ps","ps","-f",(char*)0);
     //execl("/usr/bin/ps","ps","-f",(char*)0);
     printf("execl err\n");

     exit(0);
 }

                                                                   

 三、malloc

char *s = malloc(1024);

exit(0);

1.申请1G内存不free会不会产生内存泄漏?

以下测试在红帽子系统上进行的

运行过程中申请的空间不free,就会产生内存泄漏,但是程序结束后,申请的空间会被释放回收

所以没有产生内存泄漏,操作系统具有一定的健壮性,一旦程序结束,操作系统会自动回收所有空间。

 当内存只有2G时,申请2G空间能否成功

 可以成功

虚拟内存

内存总是不够用的,要想运行一个程序,此程序必须能放在内存中才可以运行。有的程序想要运行,但由于太大了放不进内存,就无法运行。一个程序要放在内存中,就需要能创建一个页表,将物理地址和逻辑地址对应起来。程序太大,放不进去就无法运行,所以我们引入了虚拟内存。

 虚拟内存:我们在磁盘上划分一块空间,把它当做内存来用

引入虚拟内存后,将程序的一部分放在内存中,这个程序就可以运行了,想要运行在虚拟内存的部分,就会产生缺页中断,将在虚拟内存中的部分调到内存中,将内存中暂时不用的换到虚拟内存中(一般是将阻塞进程换出去),已经调出去的程序不会在内存空闲后立即再调回来,而是在用到的时候才会调回来。

2.如何判断申请空间是否可以成功?

1>物理内存剩余空间足够申请的空间,能申请成功

2>物理内存剩余空间不够,但是有虚拟内存,则看物理内存和虚拟内存总共的剩余空间够不够,如果够申请空间,则能申请成功

3.申请3G空间能不能成功

 不能成功

对于32位系统来说,进程地址空间最大4G,其中1G内核使用,剩余3G被栈、堆,数据段,代码段使用,所以malloc申请空间不能超过3G,所以申请不能成功。

64位系统可以

 

在程序中,如果没有执行malloc,就不会有堆空间,当执行一次 malloc后,系统会在堆那个位置划分一块空间,这个空间不大,大概100多k,初始化后,会在堆空间攒一些内存空间,划分为4字节,8字节,16字节,32字节,64字节...的小空间,malloc多少,给多少空间,给的都是整的(malloc7个字节,给8个字节,malloc24个字节,给32个字节,malloc64,给64),free后,我们认为是给操作系统了,实则是还给了堆,下一次malloc会重新分配出去,当进程结束或满足回收策略才会将这些空间还给操作系统。如果一次性malloc很大空间(eg:1G),直接从内存中划分,不经过堆。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值