3. Fork() and Pipe() Flashcards
How is a process created?
The first process when the OS is booted is created with a bootstrap function. Each subsequent process is created through a call to the system call fork().
What does fork() do?
Fork() creates a new process that is a copy of the calling process.
What are the two major problems with multi-threaded fork()?
- One of the threads could be blocked in the middle of doing something (on a single processor system)
- Another thread could be actually doing something (multiprocessor systems)
How does Linux handle thread state copying when fork() is called?
The OS only copies the state of the calling thread and does not copy over any other threads that might exist in the process.
What state does fork() copy?
Fork() copies one thread (the caller), the address space of the process, and the process file table.
Describe how fork() returns on success.
On success, fork() returns twice. It returns the child PID to the parent and returns 0 to the child.
Notice that the parent has a way to learn more about the child (like its exit status) via the child’s PID, but the child is not given any useful information by fork() other than the assertion that it is in fact the child.
Describe the relationship between the memory of the parent process and the memory of the child process at the end of a fork() call.
All contents of memory in the parent and child are identical.
Both child and parent have the same files open and the same position.
BUT, since they are sharing file handles, changes to the file offset made by the parent/child will be reflected in the child/parent!
What is a pipe?
An anonymous pipe object which has a read-only end and a write-only end. This allows for one-directional communication between one process and another. This allows for inter-process communication (IPC)
What does pipe() system call do?
It creates an anonymous pipe object and returns two file descriptors: one for the read-only end, and one for the write-only end.
Describe how pipe communication between two processes works.
Anything written to the write-only end of the pipe is immediately available at the read-only end of the pipe.
This just means that a pipe object contains a buffer (stored in memory) that one process is only allowed to writto and another process is only allowed to read from.
How do you establish interprocess communication between a parent and child process?
Before calling fork() the parent creates a pipe object by calling pipe().
Next, proc calls fork().
After fork() the parent closes its copy of the read-only end by calling close() on the file descriptor pointing to that end and the child closes its copy of the write-only end.
Now the parent can pass information to the child by writing to the write-only end of the pipe.
Note: Parent knows to close read-only if return code of fork() is non-zero, and child knows to close write-only if return code of fork() is 0.
What is one major concern in regular use of the fork() system call?
Copying all the state of a process is time and memory expensive. Typically, the first thing the child does after calling fork is load a new binary which destroys most of the state fork() carefully copied over.
What is a simple way to get around the wastefulness of copying proc state in fork() only to overwrite it by loading a new binary?
Change the semantics so that fork() does not copy the address space (mem state) and simply fails if child doesn’t immediately load another binary.
What can we do if we don’t want to copy all of our process state?
We can use clone() instead of fork, which allows for more control over sharing and child execution.
What is the utility that allows you to visualize the relationship between the parent and child processes?
The pstree utility