3

我读过系统函数在内部使用 execl、fork 和 wait 函数。所以,我试图在不使用它的情况下模拟系统的工作。但我无法实现同样的工作。

当我们使用系统函数调用程序时,下面的代码(之后) system() 函数调用也会执行。所以为了模拟系统功能,我在下面写了这段代码:

int main()
{
    printf("In controller Start: %d\n\n",getpid());
    system("./prog1");
    printf("Forking New Process %d\n\n",fork());
    printf("Process Id: %d\n\n",getpid());
    execl("./infinite",0);
    printf("In controller End\n\n");
    return 0;
}

在运行“无限”程序后的上述代码中,最后一行没有被打印出来。IEprintf("In controller End\n\n");

为了打印最后一行并在不使用系统函数的情况下执行“无限”程序该怎么做。

如果有人可以逐步解释系统功能的工作原理,例如系统首先调用哪个功能等等,那就太好了。

如果我们进行了除 execl 之外的简单函数调用,为什么执行不会继续到最后一行。

脚注:- 无限:是使用 C 代码创建的二进制文件。

4

6 回答 6

5

最后一行没有被打印,因为它从未被执行。execl如果一切正常,该函数永远不会返回,而是用调用中的程序替换您的程序。

fork我强烈建议您阅读和的手册页execl


简而言之,fork将当前进程一分为二,根据是返回父进程还是子进程不同返回。然后在子进程中进行exec调用,而父进程继续做它想做的事情。然而,父进程必须wait在子进程上完成,否则子进程将成为所谓的“僵尸”进程

在您的代码中,父进程子进程调用.exec

于 2013-05-06T12:24:55.590 回答
2

在您的示例中,您在父进程和子进程中执行相同的操作。您必须检查 fork 的返回值,这表明您是在父进程中还是在子进程中,然后在子进程中执行,同时在主进程中等待。

于 2013-05-06T12:25:55.720 回答
2

这是 fork 的基础

/*previous code*/
if((cpid=fork())<0){
    printf("\n\tFORK ERROR");
    exit(1);
}

if(cpid==0){        /*SON*/
    /*CODE FOR SON-your `execl("./infinite",0);` goes here*/

}else{              /*FATHER*/

    /*CODE FOR FATHER-your `printf("In controller End\n\n");` */

}

不要忘记,在进行分叉时,内存和变量会被复制到 SON pid

于 2013-05-06T12:32:44.667 回答
2

当您调用fork()时,父进程和子进程都从该点继续执行相同的代码,但每个的返回值fork()不同。通常,您会根据该返回值执行一些条件逻辑。

我想这system()会做这样的事情:

int childpid = fork();
if (childpid) {
  /* This is the parent */
  wait( childpid );
} else {
  /* This is the child */
  execl( program_name );
}

由于execl()用新的可执行文件替换当前的可执行文件,子进程将运行该可执行文件然后结束。父母将等待孩子完成然后继续。

于 2013-05-06T12:33:10.520 回答
1

您没有执行任何基于返回值的条件语句fork。如果您不确定一个进程执行该操作,exec而一个进程执行其他操作,那么两者都将执行相同的操作。

您通常要检查0然后执行您要运行的程序。0表示一切正常并且您处于子进程中。

于 2013-05-06T12:28:51.607 回答
0
int main()
{
    int pid;

    printf("In controller Start: %d\n\n",getpid());

    system("./prog1");

    pid = fork();

    printf("Forking New Process %d\n\n",pid);
    printf("Process Id: %d\n\n",getpid());

    if (pid == 0) {  /* Son process : execute the command */
        execl("./infinite",0);
    } else {  /* Original process : keep working */
        printf("In controller End\n\n");
        return 0;
    }
}
于 2013-05-06T12:29:34.440 回答