I understand the differences between fork, vfork, exec, execv, execp. So pls dont rant about it. 开发者_StackOverflow社区My question is about the design of the unix process creation. Why did the designers think of creating 2 seperate calls ( fork and exec ) instead of keeping it one tight call ( spawn ). Was good API design a reason so that developers had more control over process creation? Is it because of performance reason, so that we could delay allocating process table and other kernel structures to the child till either copy-on-write or copy-on-access?
The main reason is likely that the separation of the fork()
and exec()
steps allows arbitrary setup of the child environment to be done using other system calls. For example, you can:
- Set up an arbitrary set of open file descriptors;
- Alter the signal mask;
- Set the current working directory;
- Set the process group and/or session;
- Set the user, group and supplementary groups;
- Set hard and soft resource limits;
...and many more besides. If you were to combine these calls into a single spawn()
call, it would have to have a very complex interface, to be able to encode all of these possible changes to the child's environment - and if you ever added a new setting, the interface would need to be changed. On the other hand, separate fork()
and exec()
steps allow you to use the ordinary system calls (open()
, close()
, dup()
, fcntl()
, ...) to manipulate the child's environment prior to the exec()
. New functionality (eg. capset()
) is easily supported.
fork and exec do completely different things.
- fork() - duplicates a process
- exec() - replaces a process
There's plenty of reasons to use one without the other. You can fork off child processes that perform tasks on behalf of your controlling parent app e.g., pretty common in the unix world. And you can e.g. setup the preconditions for some other quirky application and then exec it from your launcher application without ever using fork.
From the draft book, xv6 a simple, Unix-like teaching operating system used in MIT course 6.828:
Now it should be clear why it is a good idea that fork and exec are separate calls. Because if they are separate, the shell can fork a child, use open, close, dup in the child to change the standard input and output file descriptors, and then exec. No changes to the program being exec-ed (cat in our example) are required. If fork and exec were combined into a single system call, some other (probably more complex) scheme would be required for the shell to redirect standard input and output, or the program itself would have to understand how to redirect I/O.
Basically as caf says below but providing a good reference. Implementing a simple shell would probably make the reasons very clear.
AFAIK, initially there was only fork(). But performance reasons called for creation of exec() that does not re-create the kernel structures that are going to be immediately overwritten. <-- This is wrong.
There's a performance problem when a process needs co create a child process which is not a copy of itself. A fork() copies process-related kernel data which are going to be immediately replaced by an exec(). Thus vfork() was introduced that does not copy excessive kernel data and any process data; after it, a process is expected to call something exec()-like, and the parent is suspended until the child does so. See 'Bugs' section for description of problems with vfork(), though.
fork() can only be used for creating a child process.Only replication of parent can be done. While exec() can be used for starting any new process on the system. I do not see any correlation above two.
精彩评论