Process Creation
- top -u dbennett
- You should probably read chapter 24 of Kerrisk.
- To create a process we need four basic system calls and some common sense.
- fork
- exec*
- waitpid
- exit
- common sense
- Common Sense
- as we have disucssed a process consumes memory and time (both system resources)
- When done in moderation, this is not a problem.
- When done in excess this is a denial of service attack
- See Fork Bomb
- Chris has full permission to fall on your HARD if you mess witht he production systems in the department.
- THINK, and be careful
- And use the machine CSCI310l for experiments
- Just for safety
- Don't fork inside of a loop unless you must.
- Don't put fork inside of a recursive function, unless you must.
- Don't have your forking program run your forking program.
-
- fork()
- #include < unistd.h>
- pit_t fork(void)
- Creates a new (child) process
- This is a duplicate of the parent with the following exceptions
- The child process has a new PID
- This pid is return to the parent as the value of the fork call
- a pid of 0 is returned to the child as the value of the fork call
- Child time useage is set to zero
- memory locks (we will talk about this later) are not shared
- The pending signals (we will talk about this later) are emtpy
- Semaphores (possibly later) are not inhearited.
- Times (again, later) are not inherited
- Outstanding I/O is into inherited
- The child does
- Get a copy of the parent's open file descriptors
- And open directory streams.
- If the fork fails, a -1 is returned to the parent.
- And an error code is set for perror
- After the fork, we don't know who will go next.
- And both processes, unless otherwise specified will be writing to the terminal
- Fork in most modern systems employs a copy on write scheme for creation of the process memory
- Unless the one of the processes writes to some memory location, the record is shared by both processes
- This is because most forks are immedately followed by an exec.
- And this saves time.
- pid_t waitpid(pid_t pid, int * status, int options)
- This is part of the wait family
- It waits until a specified process changes state
- Child termination
- Child stopped by a signal
- Chiled continued.
- If the exit signal is not handled, then zombies!
- Returns immediately if the child has already changed state
- If the options is 0, it only waits for exit
- WNOHANG - non-blocking, we will explore this on Monday
- WUNTRACED - child is stoped, but not traced (used for debuggers mostly)
- WCONTINUED - the process has been stopped, but asked to continue
- On exit, the signal can be interpreted with the following
- WIFEXITED(status) true if the child exited normally
- WEXITSTATUS(status) returns lower 8 bits of the exit code. Only call this if WIFEXITED is true.
- WIFSIGNALED(status) returns true if the process was terminated by a signal
- WTERMSIG(status) returns the number of the signal that caused termination, only call if WIFSIGNALED is true.
- WCOREDUMP(status) returns true if the childe dumped a core, use only if WIFSIGNALED returned true.
- WIFSTOPPED(status), true if the process was stopped by a signal.
- WIFCONTINUED(status) true if the child process was continued.
- See forker.C in ~dbennett/310/process