Fork和Execlp

时间:2011-08-23 04:38:56

标签: c linux exec fork

我尝试使用fork和execlp编写一个程序,其中父地址空间被“ls”命令替换。

#include<stdio.h>
main()
{
    int pid,j=10,fd;
    pid=fork();
    if(pid==0)
    {
        printf("\nI am the child\n");
        execlp("/bin/ls","ls",NULL);
        printf("\nStill I am the child\n");

    }
    else if (pid > 0)
    {
        printf("\n I am the parent\n");
        wait();
    } 
}

当我执行程序时,孩子的最后一行

printf("\nStill I am the child\n");

未打印。为什么呢?

5 个答案:

答案 0 :(得分:16)

exec家庭功能在成功时不会返回。

http://pubs.opengroup.org/onlinepubs/009604499/functions/exec.html

  

exec系列函数应使用新的过程映像替换当前过程映像。新图像应由称为新过程映像文件的常规可执行文件构成。成功的exec不会返回,因为调用过程映像被新的过程映像覆盖。

     

如果其中一个exec函数返回到调用进程映像,则发生错误;返回值应为-1,并设置errno以指示错误。

答案 1 :(得分:4)

exec函数不仅会执行您的命令。它们实际上会用您选择的可执行文件替换进程的执行上下文(在您的情况下为/bin/ls)。

换句话说,由于ls函数以终止其进程(“退出”或返回主函数或其他)结束,因此您的子进程将在执行{{1}时终止。 }}

您实际上可以使用此printf调用来打印一些错误,例如:

ls

答案 2 :(得分:1)

原因很简单:exec()函数仅在发生错误时才返回。对于exec()函数的相同参考手册页。

调用exec()函数时到底发生了什么:

execl()不会创建新进程 - 它会修改 VADS和相关内容 - 此外,执行上下文 也被修改了。

  • 不再使用旧的执行上下文 - 创建新的执行上下文。
    • 为新加载的应用程序创建一个新的,全新的上下文 控制权传递给调度程序 - 调度程序恢复同一个子项 使用新的可用执行上下文进行处理 - 使用此跳转 在用户空间中执行到新应用程序的入口点 - 新应用程序在同一子进程中开始执行。
      • 系统堆栈被新的hw上下文覆盖 在用户空间中恢复新程序的main()。
    • 执行上下文和代码/数据/堆栈/旧应用程序中的 儿童过程被完全摧毁 - 不再可用。
    • 只有execve()或execl()才会返回相同的应用程序/代码 当前进程的当前execve()或execl()无法加载 当前流程中的新应用程序 - 意思是唯一的时间 execv()/ execvl()或一系列的调用将在那里返回 完成execv()/ execl()/系列调用时出错。

注意:您必须验证exec()系列调用API的返回值       错误/错误代码 - 基于错误/错误代码,       您可以终止当前流程或采取其他一些流程       动作。

答案 3 :(得分:0)

在函数execlp()没有按照execlp的文档执行之后 因此你的printf()声明“我仍然是孩子”不会被执行...... !!

答案 4 :(得分:-3)

  1. 您正在将流程ID设为int类型,但实际上,要存储流程ID,您应该使用pid_t
  2. 当您使用exec系列函数时,被调用进程的整个地址空间将替换调用进程。所以,现在新进程中没有最后的printf语句,实际上甚至进程的进程ID也没有改变