【linux】进程替换

简介: 【linux】进程替换

1.代码看现象

#include<stdio.h>
 #include<unistd.h>
 #include<stdlib.h>
 #include<sys/types.h>
 #include<sys/wait.h>
 int main()
  {
      printf("test begin\n");
     int id=fork();//产生子进程
     if(id==0)
     {sleep(2);
     execl("/usr/bin/ls","ls","-l","-a",NULL);//子进程替换ls进程
     exit(1);//如果走到这里说明替换失败//替换失败的原因可能是因为无该进程
    }
     int status=0;
     int reid=waitpid(id,&status,0);//阻塞等待子进程的状态,等待回收资源
     if(reid>0)//说明子进程资源已经回收,子进程的进程号>0
     {
      printf("father wait success,child exit code:%d\n",WEXITSTATUS(status));//子进程的退出码
     }
     printf("test end\n");
     return 0;            
  } 

1.疑问

为什么这里的退出码是0,不是1呢?

原因是由于子进程被替换成ls进程后,旧的子进程后面就不执行了,所以exit(1)这句代码就不会执行,而是执行新进程ls,而进程ls执行成功,所以退出码为0.

验证:

我们可以通过改变要替换的子进程不存在,就不会替换子进程,所以退出码会是1

2.execl函数参数分析


总结:1.execl函数,可以执行起来新的程序

2.execl函数,执行完毕后,后续的代码不见了,因为被替换了

3.execl函数的返回值可以不用关心,只要替换成功了,就不会往后继续进行了,只要继续运行了,一定是替换失败了

2.解释原理

3.进程替换(c替换c++)

子进程要替换的cpp程序

include<iostream>
   #include<unistd.h>
   #include <sys/types.h>
   
   using namespace std;
   int main()
   {
   cout<<"this is c++"<<getpid()<<endl;
   cout<<"this is c+"<<getpid()<<endl;
   cout<<"this is c++"<<getpid()<<endl;
   cout<<"this is c++"<<getpid()<<endl;
   
  
  
     

由于要编译两个程序,所以写个makefile来进行编译

.PHONY:all
   all:exe exe1 
exe:test.c
    gcc -o exe test.c
exe1:ans.cc
    g++ -o exe1 ans.cc -std=c++11
 .PHONY:clean
    rm -rf exe exe1 

在makefile里面他只会默认给第一个依赖列表通过依赖方法形成目标文makefile/make会自动根据文件中的依赖关系,进行自动推导,帮助我们执行所有相关的依赖方法.

test.c修改

4.其他的进程替换函数

1.int execv(const char *path, char *const argv[])

我们通过命令行参数表的形式获取执行该程序要怎么做

#include<stdio.h>
   #include<unistd.h>
   #include<stdlib.h>
   #include<sys/types.h>
   #include<sys/wait.h>
   int main()
   {
   printf("test begin\n");
      int id=fork();
     if(id==0)
     { 
       sleep(2);
       char *const argv[]=
       {
     (char*)  "ls",
     (char*)  "-l",
      (char*) "-a",
      (char*) "--color",
       NULL
       };
      execv("/usr/bin/ls",argv);                                                                                     
     exit(1);
     }
     int status=0;
     int reid=waitpid(id,&status,0);
     if(reid>0)
         {
      printf("father wait success,child exit code:%d\n",WEXITSTATUS(status));
    }
    printf("test end\n");
    return 0;
  }

命令行参数指针数组中要存对应指令以及选项的字符串地址,强转为char*,字符串的首地址

2.int execvp(const char *file, char *const argv[])

第一个参数直接写程序名称,p:代表路径会自动在环境变量PATH里面找

倒数第二个v:vector,用数组来记录程序怎么执行

#include<stdio.h>
 #include<unistd.h>
 #include<stdlib.h>
 #include<sys/types.h>
 #include<sys/wait.h>
  int main()
  {
   printf("test begin\n");
      int id=fork();
     if(id==0)
     { 
       sleep(2);
       char *const argv[]=
       {
     (char*)  "ls",
     (char*)  "-l",
      (char*) "-a",
      (char*) "--color",
       NULL
      };
      execvp("ls",argv);                                                                                             
      exit(1);
     }
     int status=0;
     int reid=waitpid(id,&status,0);
    if(reid>0)
    {
      printf("father wait success,child exit code:%d\n",WEXITSTATUS(status));
     }
     printf("test end\n");
     return 0;
  }

3.int execlp(const char *file, const char *arg, ...)

p:路径可以在PATH环境变量里面找

#include<stdio.h>
 #include<unistd.h>
 #include<stdlib.h>
 #include<sys/types.h>
 #include<sys/wait.h>
 int main()
  {
   printf("test begin\n");
      int id=fork();
     if(id==0)
     { 
       sleep(2);
           execlp("ls","ls","-a","-l",NULL);                                                                     
      exit(1);
     }
     int status=0;
     int reid=waitpid(id,&status,0);                                                           
     if(reid>0)                                                                                
     {
     printf("father wait success,child exit code:%d\n",WEXITSTATUS(status));
    }
     printf("test end\n");
    return 0;
  }

4.int execvpe(const char *file, char *const argv[],char *const envp[]);

`最后的e:表示环境变量

替换子进程的cpp

#include<iostream>
   #include<unistd.h>
   #include <sys/types.h>
  
  using namespace std;
   int main(int argc,char*argv[],char*envp[])
   {
    for(int i=0;i<argc;i++)
   {cout<<argv[i]<<endl;}
   for(int i=0;envp[i];i++)
   {
    cout<<envp[i]<<endl;                                                                                             
  
  
  
   }
  
  
  }
#include<stdio.h>
  #include<unistd.h>
  #include<stdlib.h>
  #include<sys/types.h>
  #include<sys/wait.h>
  int main()
   {
   printf("test begin\n");
     int id=fork();
     if(id==0)
     {
       sleep(2);
      char *const argv[]=
      {
     (char*)  "./",
     (char*)  "exe1",
       NULL
      };   
      char *const engv[]=
 
      {
        (char*)  "HELLO=1111111111",
        (char*)  "ERZI=22222222222",
       (char*) "SOUZI=33333333333",
        (char*) "GUIZI=44444444444",                                                                                 
       NULL
      };
      execvpe("exe1",argv,engv);
      exit(1);
     }
     int status=0;
     int reid=waitpid(id,&status,0);
     if(reid>0)
     {
      printf("father wait success,child exit code:%d\n",WEXITSTATUS(status));
     }
     printf("test end\n");
     return 0;
  }
 

该cpp程序父进程是c程序,爷爷进程是bash,要获取爷爷的环境变量用上面的方法修改

总结第四个函数:

1.用全新的环境变量给子进程

2.用爷爷进程的环境变量给孙子进程,environ

3.老的环境变量加一些,putenv

而对应putenv,我们可以查一下手册

man putenv
• 1


目录
相关文章
|
26天前
|
资源调度 Linux 调度
Linux c/c++之进程基础
这篇文章主要介绍了Linux下C/C++进程的基本概念、组成、模式、运行和状态,以及如何使用系统调用创建和管理进程。
29 0
|
3月前
|
网络协议 Linux
Linux查看端口监听情况,以及Linux查看某个端口对应的进程号和程序
Linux查看端口监听情况,以及Linux查看某个端口对应的进程号和程序
571 2
|
3月前
|
Linux Python
linux上根据运行程序的进程号,查看程序所在的绝对路径。linux查看进程启动的时间
linux上根据运行程序的进程号,查看程序所在的绝对路径。linux查看进程启动的时间
64 2
|
1天前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
19 4
linux进程管理万字详解!!!
|
2天前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
3天前
|
消息中间件 存储 Linux
|
9天前
|
运维 Linux
Linux查找占用的端口,并杀死进程的简单方法
通过上述步骤和命令,您能够迅速识别并根据实际情况管理Linux系统中占用特定端口的进程。为了获得更全面的服务器管理技巧和解决方案,提供了丰富的资源和专业服务,是您提升运维技能的理想选择。
10 1
|
21天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
【10月更文挑战第9天】本文将深入浅出地介绍Linux系统中的进程管理机制,包括进程的概念、状态、调度以及如何在Linux环境下进行进程控制。我们将通过直观的语言和生动的比喻,让读者轻松掌握这一核心概念。文章不仅适合初学者构建基础,也能帮助有经验的用户加深对进程管理的理解。
16 1
|
26天前
|
消息中间件 Linux API
Linux c/c++之IPC进程间通信
这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。
22 0
Linux c/c++之IPC进程间通信
|
26天前
|
Linux C++
Linux c/c++进程间通信(1)
这篇文章介绍了Linux下C/C++进程间通信的几种方式,包括普通文件、文件映射虚拟内存、管道通信(FIFO),并提供了示例代码和标准输入输出设备的应用。
17 0
Linux c/c++进程间通信(1)