What is the use of fork() - ing before exec()?

sha*_*har 5 c unix process

In *nix systems, processes are created by using fork() system call. Consider for example, init process creates another process.. First it forks itself and creates the a process which has the context like init. Only on calling exec(), this child process turns out to be a new process. So why is the intermediate step ( of creating a child with same context as parent ) needed? Isn't that a waste of time and resource, because we are creating a context ( consumes time and wastes memory ) and then over writing it?

为什么这没有实现为分配一个空的内存区域然后调用 exec()?这样可以节省时间和资源,对吗?

use*_*342 4

中间步骤使您能够在子进程中设置共享资源,而外部程序不会意识到这一点。典型的例子是构造一个管道:

\n\n
// read output of "ls"\n// (error checking omitted for brevity)\nint pipe_fd[2];\npipe(&pipe_fd);\nif (fork() == 0) {       // child:\n    close(pipe_fd[0]);   // we don\'t want to read from the pipe\n    dup2(pipe_fd[1], 1); // redirect stdout to the write end of the pipe\n    execlp("ls", "ls", (char *) NULL);\n    _exit(127);          // in case exec fails\n}\n// parent:\nclose(pipe_fd[1]);\nfp = fdopen(pipe_fd[0], "r");\nwhile (!feof(fp)) {\n    char line[256];\n    fgets(line, sizeof line, fp);\n    ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意标准输出到管道的重定向是如何在子进程中、在fork和之间完成的exec。当然,对于这个简单的情况,可能有一个生成 API,它可以在给定正确的参数的情况下自动执行此操作。但该fork()设计允许对子 \xe2\x80\x94 中的每进程资源进行任意操作,可以关闭不需要的文件描述符、修改每进程限制、删除特权、操作信号掩码等。如果没有fork(),用于生成进程的 API 最终会变得非常臃肿或不太有用。事实上,竞争操作系统的进程生成调用通常介于两者之间。

\n\n

至于内存的浪费,可以通过写时复制技术来避免。fork()不会为子进程分配新内存,而是将子进程指向父进程的内存,并指示仅当页面被写入时才复制该页面。这fork()不仅提高了内存效率,而且速度也很快,因为它只需要复制一个“目录”。

\n