IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 【Linux】进程替换(函数) -> 正文阅读

[游戏开发]【Linux】进程替换(函数)

一、进程的程序替换

1. 程序替换函数命名理解

  • l(list) : 表示参数采用列表 (可变参数列表)
  • v(vector) : 参数用数组
  • p(path) : 有p自动搜索环境变量PATH
  • e(env) : 表示自己维护环境变量
#include <unistd.h>`
//间隔都是相似的
int execl(const char *path, const char *arg, ...);
int execv(const char *path, char *const argv[]);

int execlp(const char *file, const char *arg, ...);
int execvp(const char *file, char *const argv[]);

int execle(const char *path, const char *arg, ...,char *const envp[]);
int execve(const char *path, char *const argv[], char *const envp[]);

如果想要子进程进行一个新的程序

进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变


2. execl进程替换 路径 + 执行指令

execl函数:

  • 如果调用失败,不会执行该代码

  • 如果调用成功则加载新的程序从启动代码开始执行,不再返回。 如果调用出错则返回-1, 所以exec函数只有出错的返回值而没有成功的返回值

int execl(const char *path, const char *arg, ...);
//全路径/文件名    //可变参数列表怎么执行就写什么命令,结束用NULL

image-20220416093038578

  1 #include <iostream>                                
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <sys/types.h>
  5 #include <sys/wait.h>
  6 #include <unistd.h>
  7 #include <stdio.h>
  8 
  9 using namespace std;
 10 
 11 
 12 int main()
 13 {
 14   cout << "hello world" << endl;
 15 
 16   execl("/usr/bin/ls", "ls", "-a", "-l", "-d", NULL);
 17 //之后不会进行下面代码 
 18   cout << "hello world" << endl;
 19 
 20 
 21   return 0;
 22 }

image-20220416103400055


程序替换的本质是把程序的进程代码+数据加载进特定进程的上下文中

C/C++程序运行,必须的先加载到内存中!
如何加载? 加载器:exec*程序替换函数

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支)

子进程调用一种exec函数执行另一个程序,此时发生写实拷贝,不影响父进程


makefile如何生成两个可执行文件?

.PHONY:all 
all:mytest1 mytest2

mytest2:test2.c
	gcc $^ -o $@

mytest1:test1.c
	gcc $^ -o $@

.PHONY:clean

clean:
	rm -f mytest1 mytest2

image-20220426163353879

使用execl用一个可执行程序执行另外一个可执行程序

#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
  if(fork() == 0)
  {
    printf("link start\n");
    execl("./mytest2", "./mytest2", NULL);
    exit(1);
  }
  waitpid(-1, NULL, 0);
  printf("over\n");

  return 0;
}

image-20220426170935335


3. execv 路径 + 使用数组存储指令

就是把指令放在一个数组里

int main()
{
   if(fork() == 0)
   {
     char* const argv[] = {
       "ls",
       "-a",
       "-l",
       "-d",
       NULL
     };
     printf("link start\n");
    // execl("/usr/bin/ls", "ls", "-a", "-l", "-d", NULL);  
     execv("/usr/bin/ls", argv);
     printf("end of order\n");
     exit(1);
   }
   waitpid(-1, NULL, 0);                             
   printf("over\n");
 
   return 0;
}

image-20220426152001741

和上面一样


4. execlp 文件名+ 执行指令 + execvp介绍

可以从环境变量自动找到文件去执行

int execlp(const char *file, const char *arg, ...);
//指令名称,  指令如何执行

#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
  if(fork() == 0)
  {
    printf("link start\n");
    execlp("ls", "ls", "-a", "-l", "-d");
    /*
    char* const argv[] = {
       "ls",
       "-a",
       "-l",
       "-d",
       NULL
     };
     execvp("ls", argv);
    */
    exit(1);
  }
  waitpid(-1, NULL, 0);
  printf("over\n");

  return 0;
}

image-20220426153722667


5. execle 路径 + 执行指令 + 自己组建环境变量写进数组env + execve介绍

也是用一个程序调用另外一个程序,但环境变量是自己的环境变量,不是系统的,通过获取环境变量查看:

test1:

int main()
{
  if(fork() == 0)
  {
    printf("link start\n");
    char* const env[]= {
      "env = 123",
      NULL
    };
    /*
     char* const argv[] = {
       "./mytest2",
       NULL
     };
     execve("./mytest2",argv,NULL,env);
    */
    execle("./mytest2","./mytest2",NULL,env);
    exit(1);
  }
  waitpid(-1, NULL, 0);
  printf("over\n");

  return 0;
}

test2

#include <stdio.h>

int main()
{
  extern char** environ;
  for(int i = 0; environ[i]; i++)
  {
    printf("%s\n", environ[i]);
  }

  printf("over");

  return 0;
}

image-20220426212331597


6. 运行一个py程序

py:

#!/usr/bin/python3

print("hello world\n");

test1.c

#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>


int main()
{
  if(fork() == 0)
  {
    printf("link start\n");

    execl("/usr/bin/python3","python","test3.py",NULL);
    exit(1);
  }
  waitpid(-1, NULL, 0);
  printf("over\n");

  return 0;
}

image-20220426215146959


总结:

2的手册是系统调用,3的手册是库

image-20220426220421455

这里面缺少了一个execve

这里的几个都是经过封装,最终还是调用execve的

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-28 12:10:15  更:2022-04-28 12:10:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/17 0:50:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码