zoukankan      html  css  js  c++  java
  • linux 之进程基础 (四)、进程API之进程执行exec函数簇

    4. 进程API之进程执行exec函数簇

    int execl(const char *path, const char *arg, ...
                           /* (char  *) NULL */);
    int execlp(const char *file, const char *arg, ...
                           /* (char  *) NULL */);
    int execle(const char *path, const char *arg, ...
                           /*, (char *) NULL, char * const envp[] */);
    int execv(const char *path, char *const argv[]);
    int execvp(const char *file, char *const argv[]);
    int execvpe(const char *file, char *const argv[],
                           char *const envp[]);
    // 函数返回值: -1 为出错
    

    4.1 exec()函数簇说明

    4.1.1

    可执行文件查找方式:

    • 带p:对文件查找方式为p的(以p结尾的函数)可以只给出文件名,系统会自动从环境变量“$PATH”所包含的路径中进行查找。
    • 不带p:需要提供完整的路径名。

    向新程序传递环境表的方式:

    • 带e:接受一个附加的环境参数列表,参数格式为NULL结尾的字符串数组,且字符串的格式为“VARIABLE=value”。
    • 不带e: 不能接受附加的环境变量。

    向新程序传递参数表的方式 :

    • 带l:以函数名的第五位字母来区分,字母为“l”(list)的表示:逐个列举的方式;
    • 带v:字母为“v”(vertor)的表示将所有参数构造成指针数组传递,其语法为char *const argv[]

    4.1.2 exec 函数簇功能

    提供了一种在一个进程中启动另一个程序的方法。另一个程序可以是一个二进制文件,也可以是一个脚本。

    4.2 使用exec函数簇的函数

    4.2.1 什么时候使用exec函数簇

    • 当当前进程已经不能再为系统和用户做事情时,它就可以调用exec函数簇,去执行新的程序。(当fork的子进程没用的时候调用exec)
    • 当某个进程想要执行另一个程序,它就可以在fork一个子进程后,在子进程中直接调用exec函数簇去执行想要执行的程序(执行fork 后马上调用exec)

    4.2.2 这样做的好处

    当一个进程不再起作用时,按照正常的逻辑应该结束该进程,然后回收其资源。但是我们可以不让他结束,而是利用它的task_struct空壳取装载另外一个程序。(对应上述第一种情况)

    就是使用fork创建一个进程后,原本进程中的task_struct 结构体是复制父进程而来的。 每当进程调用一种exec函数时,该进程完全由新程序代换。也就是将指定的程序的 堆栈、数据段等内容,覆盖原本的task_struct结构体。新程序从main函数开始执行。exec并不创建新进程,所以前后进程ID也不会变,也就是task_struct中的pid 字段等保持不变。exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。(对应上述第二种情况)

    相当于更加快速的执行一个程序。 例如exec函数执行的程序是a.out。 如果使用./a.out执行这个程序的话,需要内核为其开辟空间等。但是如果使用exec函数簇的话,就直接将该函数的堆栈以及代码段数据用用新程序填充了。因此省了许多内核的操作,效率提高了很多。

    4.3 使用exec函数簇的注意事项

    在使用exec函数族时,一定要加上错误判断语句:
    常见的错误原因有:
    1)找不到文件或路径,此时errno被设置为ENOENT
    2)数组argv和envp忘记用NULL结束,此时errno被设置为EFAULT
    3)没有对应可执行文件的运行权限,此时errno被设置为EACCESS
    4)这6个函数中只用execve是系统调用,其他5个都是库函数,它们只是在execve基础之上进行封装,最终还是会调用该函数。

    4.4 环境表

    每个程序都接收到一张环境变量表。与参数表一样,环境表也是一个字符指针数组,其中每个指针包含一个以NULL结束的字符串的地址。全局变量environ则包含了该指针数组的地址。
    在这里插入图片描述实际上main 函数的真正形式 最后一个参数 是环境变量表。

  • 相关阅读:
    C#Type类中的IsAssignableFrom、IsInstanceOfType、IsSubclassOf
    C# IsAssignableFrom & IsInstanceOfType & IsSubclassOf & Is
    VS2017桌面应用程序打包成.msi或者.exe
    C# 10个常用特性
    ADO.NET 的六大对象及其关系图
    Expression表达式树(C#)
    表达式树 Expression Trees
    特性 Attribute
    C# 特性(attribute)
    Vue中使用axios
  • 原文地址:https://www.cnblogs.com/lasnitch/p/12764130.html
Copyright © 2011-2022 走看看