Process Control in Unix Operating Systems Hebrew University Spring 2004
Unix Process Model What is a processes? Properties of a process Processes organization Interacting with a process
Resources Advanced Programming in the Unix Environment, Stevens [ St 48] POSIX.1 Spec
What is a process An entry in the kernel’s process table Most common unit of execution Execution state Machine instructions, data and environment
Properties of a process Process ID Parent Process ID Process group ID Session ID User ID of the process Group ID of the process Effective user ID Effective group ID
Properties of a Process - cont Controlling terminal Current working directory Root directory Open files descriptors File mode creation mask Resource limits Process times
Process Trees Only an existing process can create a new process Parent-Child relations 1 0 init
Who am I? getpid Returns the PID of the current process #include pid_t getpid(void);
Who is my parent? getppid Returns the PID of the parent of the current process #include pid_t getppid(void);
Talking directly to a process Send a signal The ONLY way to talk to a process Lots of signals More next week #include int kill(pid_t pid, int sig)
Creating a process Only an existing process can create a new process Step 1: Make a clone of yourself Step 2: Have the clone change itself
Fork Make a clone of myself ONLY difference is PID and PPID! Very cheap, Copy on Write -1 = failure –Reason via ERRNO #include pid_t fork(void);
Fork Example if ( (pid = fork()) == 0 ) { code for child } else { code for parent }
Changing a process Execute a new program in this space argv and envp terminated by null pointer NEVER returns on success, -1 and errno on failure #include int execve(const char *filename, char *const argv[], char *const envp[]);
Exec example if ((pid = fork()) == 0 ){ exec( arguments ); exit(-1); } // parent continues here
Better ways #include extern char **environ; int execl(const char *path, const char *arg, …); int execlp(const char *file, const char *arg, …); int execle(const char *path, const char *arg, …, char *const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]);
Rendezvous Meeting up with your child processes Resources are freed only when the parent acknowledges the death of the child #include pid_t wait(int *status); pid_t waitpid(pid_t pid, int *status, int options);
wait status returns WIFEXITED(status) WEXITSTATUS(status) WIFSIGNALED(status) –WIFTERMSIG(status) WIFSTOPPED(status) –WSTOPSIG(status)
Leaving a process Leave and tell my parent why I left NEVER returns Flush output buffers Close all open streams Call exit handlers #include void exit(int status);
Leaving a process (quickly) Just like exit, but…. Don’t call the exit handlers Don’t flush output buffers Close file descriptors #include void _exit(int status);
When to use _exit In the fork branch of a C++ child Fail Fast!
Orphans A process whose parent has exited. Orphaned processes are inherited by init Its slot in the process table is immediately released when an orphan terminates.
Zombies A process that no longer exists, but still ties up a slot in the system process table Equivalently: –A process that has terminated, but whose parent exists and has not waited/acknowledged the child's termination
Daemons Leaving Home: Disconnecting from my parent so that I can live my own life Somewhat tricky to do correctly Examples: –inetd –atd –nfsd
How to make a daemon Fork -- Create pid-1 Fork again – Create pid-2 pid-1 exits, pid-2 is now an orphan Chdir(“/”) – free current directory Close all file descriptors (0…MAXINT)