Concurrency
Three possibilities can happen to the creator during process creation:
- The child process is created and runs concurrently with the parent.
In this case, as soon as process creation is successful, the process manager
replies to the parent, and the child is made READY. If it's
the parent's turn to run, then the first thing it does is return
from the process-creation function. This may not be the case
if the child process was created at a higher priority than the
parent (in which case the child will run before the parent gets
to run again).
This is how fork(), forkpty(), popen(), and spawn() work. This is also how the spawn*() family of functions work when you specify a mode of P_NOWAIT or P_NOWAITO.
- The child replaces the parent. In fact, they're not really parent
and child, because the image of the given process simply replaces that of
the caller. Many things will change, but those things that uniquely
identify a process (such as the process ID) will remain the same.
This is typically referred to as
execing,
since usually the exec*() functions are used.Many things will remain the same (including the process ID, parent process ID, and file descriptors) with the exception of file descriptors that had the FD_CLOEXEC flag set using fcntl(). See the exec*() functions for more on what will and will not be the same across the exec.
The login command serves as a good example of execing. Once the login is successful, the login command execs into a shell.
Functions you can use for this type of process creation are the exec*() and spawn*() families of functions, with mode passed as P_OVERLAY.
- The calling thread in the parent waits until the child terminates.
You can make this happen by passing the mode as P_WAIT when you call one of
the spawn*() functions.
Note that what is going on underneath the covers in this case is that spawn() is called as in the first possibility above. Then, after it returns, waitpid() is called in order to wait for the child to terminate. This means that you can use any of the functions mentioned in our first possibility above to achieve the same thing if you follow them by a call to one of the wait*() functions (e.g., wait() or waitpid()).