ToB企服应用市场:ToB评测及商务社交产业平台

标题: Linux:进程控制(二.详细解说进程步伐替换) [打印本页]

作者: 小小小幸运    时间: 2024-6-29 10:26
标题: Linux:进程控制(二.详细解说进程步伐替换)
上次讲了:Linux:进程地点空间、进程控制(一.进程创建、进程克制、进程等待)


  

1.进程步伐替换

   之前我们举行的步伐演示里,都只能运行自己的代码。那我们怎么样才能执行其他步伐的代码呢?(例如在步伐里利用ls之类的指令)就可以利用进程步伐替换,一开始我们先只看单进程的情况。后面在引入多进程的情况
  1.1概念

进程步伐替换是指在运行过程中将一个进程的地点空间中的代码、数据和堆栈等内容完全替换为另一个步伐的代码、数据和堆栈的过程。这个过程通常是由操作系统提供的 exec 系列函数来实现的:

1.2原理



1.3利用一个exec 系列函数

execl()函数

execl函数是Linux系统中用于执行新步伐的函数之一,它属于exec函数族的一部分。这个函数的作用是在当进步程的上下文中启动一个新的步伐,并替换当进步程的映像为新的步伐映像。调用execl函数后,当进步程将克制执行,并由新的步伐开始执行。
  1. #include<unistd.h>
  2. int execl(const char *path, const char *arg0, ... /* (char  *) NULL */);
复制代码
参数说明:

   execl函数会根据提供的路径path找到并执行相应的步伐,同时将arg0及厥后面的参数作为新步伐的下令行参数通报。注意,参数列表必须以NULL末端,这是告诉execl参数列表结束的标记。
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <sys/wait.h>
  6. int main()
  7. {
  8.         printf("I'm a process, pid: %d\n", getpid());
  9.         printf("execl begin...\n");
  10.         int a=execl("/usr/bin/ls", "ls", "-a", "-l", NULL);
  11.         printf("execl end...\n");
  12.         return 0;
  13. }
复制代码

假如execl函数调用乐成,那么它实际上不会返回,因为当进步程的映像已经被新步伐替换。假如调用失败,它会返回-1,并设置全局变量errno以指示错误缘故原由。常见的错误缘故原由大概包括文件未找到、权限不敷等。
execl函数和其他exec函数一样,不会创建新的进程。它们只是在当进步程的上下文中启动另一个步伐。
因此,调用execl前后,进程的ID(PID)不会改变。同时,由于execl会替换整个进程映像,所以在调用execl之前,通常必要确保当进步程的所有打开的文件描述符、内存分配等都被适当地处置惩罚或释放,因为这些资源不会被新步伐继承。
结论与细节

2.多进程时的步伐替换

我们可以创建一个子进程,由子进程来举行步伐替换,父进程来等待效果就可以。为什么? 父进程能得到子进程的执行效果
我们知道父进程与子进程映射到同一块代码,那么子进程举行步伐替换后,不是会覆盖吗,替换为什么不影响父进程?
   进程具有独立性,在举行步伐替换时要举行写时拷贝
  写时拷贝的本质就是开辟新的空间
  shell是如何运行起来一个指令的?
   首先创建子进程,shell会waitpid()等待进程效果,子进程会继承shell的代码,但是不影响。子进程举行步伐替换,替换为我们输入的指令
  1. int main()
  2. {
  3.         pid_t id = fork();
  4.         if (id == 0)
  5.         {
  6.                 printf("I'm a process, pid: %d\n", getpid());
  7.                 printf("execl begin...\n");
  8.                 execl("/usr/bin/ls", "ls", "-a", "-l", NULL);
  9.                 printf("execl end...\n");
  10.                 exit(1);
  11.         }
  12.         pid_t rid = waitpid(id, NULL, 0);
  13.         if (rid > 0)
  14.         {
  15.                 printf("wait successfully\n");
  16.         }
  17.         return 0;
  18. }
复制代码

3.其他几个exec系列函数


  1. int execvp(const char *file, char *const argv[]);
复制代码
file 是要执行的可执行文件的文件名,argv 是一个以 NULL 末端的参数数组,此中每个元素都是一个字符串,表示下令行参数。
   既有字母p 又有v,结合上面那两种就行
     进程步伐替换不会替换环境变量的
    putenv 是 C 语言中的一个库函数,它界说在 <stdlib.h> 头文件中。这个函数用于将字符串添加到环境变量中,或者修改已经存在的环境变量的值。
  1. int putenv(const char *string);
复制代码
  也可以调用其他语言的步伐

code.c里:
  1. int main()
  2. {
  3.         char* const env[] = {
  4.                 (char*)"first",
  5.                 (char*)"second",
  6.                 NULL };
  7.         pid_t id = fork();
  8.         if (id == 0)
  9.         {
  10.                 printf("I'm a process, pid: %d\n", getpid());
  11.                 printf("execl begin...\n");
  12.                 execle("./mytest", "mytest", NULL, env)
  13.                 printf("execl end...\n");
  14.                 exit(1);
  15.         }
  16.         pid_t rid = waitpid(id, NULL, 0);
  17.         if (rid > 0)
  18.         {
  19.                 printf("wait successfully\n");
  20.         }
  21.         return 0;
  22. }
复制代码
test.cpp里:
  1. #include <iostream>
  2. #include <unistd.h>
  3. using namespace std;
  4. int main()
  5. {
  6.         for (int i = 0; environ[i]; i++)
  7.         {
  8.                 printf("env[%d]: %s\n", i, environ[i]);
  9.         }
  10.         cout << "This is C++" << endl;
  11.         return 0;
  12. }
复制代码

当然我们也能传系统环境变量,但是没必要,如许的话直接默认就行
  1. execle("./mytest", "mytest", NULL, environ)//传入这个全局变量
复制代码
想要生成两个可执行文件的makefile

  1. .PHONY:all
  2. all:mycode mytest
  3. mycode:code.c
  4.         gcc -o $@ $^
  5. mytest:test.cpp
  6.         g++ -o $@ $^ -std=c++11
  7. .PHONY:clean
  8. clean:
  9.         rm -f mycode mytest
复制代码

今天就到这里啦,感谢大家支持

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4