Processes
CS-446/646
C. Papachristos
Robotic Workers (RoboWork) Lab
University of Nevada, Reno
Process Abstraction
CS446/646 C. Papachristos
Process Management
Uniprogramming - Simple Process Management: One-at-a-time
A Process runs from start to full completion
CS446/646 C. Papachristos
Process Management
Multiprogramming – Multiple Process Management: Multiple at-the-same-time
Modern OSs run multiple processes Concurrently
CS446/646 C. Papachristos
Windows 10 Task Manager
Process Management
Multiprogramming – Multiple Process Management : Multiple at-the-same-time
Advantages: Increase utilization and overall speed
Note: A will however run slower than if it had whole machine to itself
CS446/646 C. Papachristos
vim
gcc
wait for input
wait for input
A
B
80s
20s
A
B
Kernel & Processes
Process Components
A Process encapsulates the full State of a Program in execution
CS446/646 C. Papachristos
Kernel & Processes
From the Process’ viewpoint
Each Process has own view of the Machine
*(char *)0xc000 is different for Process1 & Process2
Note: Above is C code.
CS446/646 C. Papachristos
Kernel & Processes
CS446/646 C. Papachristos
Process A
Process B
Kernel & Processes
Process Address Space
CS446/646 C. Papachristos
// works with GCC
register void *sp asm ("sp");
printf("%p", sp);
Stack
Pointer
Program
Counter
Kernel & Processes
Process
Address
Space
(Better picture)
Note:
In reality, also Address Randomization takes place…
User Virtual Memory
Kernel Virtual Memory
0xFFFFFFFF
0xC0000000
0x00000000
0x08048000
Grows Downward
Grows Upward
OS Kernel Space
Not accessible by User Mode code
Invalid Virtual Addresses (for this Process)
C. Papachristos
0xBFFFFFFF
Stack (User-Space)
Automatic variables, return Addresses, …
Uninitialized Data (BSS)
Uninitialized (zero-initialized) static variables
Initialized Data Segment (DS)
Initialized static variables
Code / Text Segment
Program binary image
Mapped Memory (also Dynamic)
Heap
(part of) Dynamic Memory
Kernel & Processes
Process Naming
A Process is named using its Process IDentifier (PID)
CS446/646 C. Papachristos
Linux top (Table of Processes)
Kernel & Processes
Inter-Process Communication (IPC)
Interaction between Processes is sometimes desired
Real-time interaction is usually required. Methods:
CS446/646 C. Papachristos
Kernel & Processes
CS446/646 C. Papachristos
Kernel & Processes
Inter-Process Communication (IPC)
Unix PIPE: Creates a one-way communication channel (through the Kernel-Space)
int pipe(int fds[2])
How can one Process (e.g. reader) know of another Process’ (e.g. writer) setting-up of a Pipe connection?
CS446/646 C. Papachristos
int pipefd[2];
pipe(pipefd);
switch( pid = fork() ) {
case -1: perror("fork error"); exit(1);
case 0: close(pipefd[0]); // child process
// write to pipefd[1], close it when done� // (or on cleanup during child process termination)
break;
default: close(pipefd[1]); // parent process
// read from pipefd[0], close it when done � // or child terminates (check with wait())
break;
}
Kernel & Processes
Inter-Process Communication (IPC)
Unix Shared Memory: Direct communication based on Memory operations (from User-Space)
int shmget(key_t key, size_t size, int shmflg);
int shmat(int shmid, const void *addr, int flg);
int shmdt(const void *shmaddr);
Remember: Shared Memory access also requires Synchronization (more on Synchronization Mechanisms later)
CS446/646 C. Papachristos
Kernel & Processes
Inter-Process Communication (IPC)
UNIX Signals (again through the Kernel-Space)
sighandler_t signal(int signum, sighandler_t handler);
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
int kill(pid_t pid, int sig);
int killpg(int pgrp, int sig);
CS446/646 C. Papachristos
Note: If pid is positive, then signal sig is sent to the Process with the ID specified by pid.
If pid equals 0, then sig is sent to every Process in the Process Group of the calling Process.
If pid equals -1, then sig is sent to every Process for which the calling Process has permission to send signals, except for Process 1 (init), but see below.
If pid is less than -1, then sig is sent to every Process in the Process Group whose ID is -pid.
Note: typedef void (*sighandler_t)(int);
i.e. Pointer to void function with a single int argument.
Kernel & Processes
Process Implementation
A data structure for each process: Process Control Block (PCB)
The Process is a heavyweight Abstraction!
CS446/646 C. Papachristos
Kernel & Processes
struct proc (Solaris OS)
CS446/646 C. Papachristos
/*
* One structure allocated per active process. It contains all
* data needed about the process while the process may be swapped
* out. Other per-process data (user.h) is also inside the proc structure.
* Lightweight-process data (lwp.h) and the kernel stack may be swapped out.
*/
typedef struct proc {
/*
* Fields requiring no explicit locking
*/
struct vnode *p_exec; /* pointer to a.out vnode */
struct as *p_as; /* process address space pointer */
struct plock *p_lockp; /* ptr to proc struct's mutex lock */
kmutex_t p_crlock; /* lock for p_cred */
struct cred *p_cred; /* process credentials */
/*
* Fields protected by pidlock
*/
int p_swapcnt; /* number of swapped out lwps */
char p_stat; /* status of process */
char p_wcode; /* current wait code */
ushort_t p_pidflag; /* flags protected only by pidlock */
int p_wdata; /* current wait return value */
pid_t p_ppid; /* process id of parent */
struct proc *p_link; /* forward link */
struct proc *p_parent; /* ptr to parent process */
struct proc *p_child; /* ptr to first child process */
struct proc *p_sibling; /* ptr to next sibling proc on chain */
struct proc *p_psibling; /* ptr to prev sibling proc on chain */
struct proc *p_sibling_ns; /* prt to siblings with new state */
struct proc *p_child_ns; /* prt to children with new state */
struct proc *p_next; /* active chain link next */
struct proc *p_prev; /* active chain link prev */
struct proc *p_nextofkin; /* gets accounting info at exit */
struct proc *p_orphan;
struct proc *p_nextorph;
*p_pglink; /* process group hash chain link next */
struct proc *p_ppglink; /* process group hash chain link prev */
struct sess *p_sessp; /* session information */
struct pid *p_pidp; /* process ID info */
struct pid *p_pgidp; /* process group ID info */
/*
* Fields protected by p_lock
*/
kcondvar_t p_cv; /* proc struct's condition variable */
kcondvar_t p_flag_cv;
kcondvar_t p_lwpexit; /* waiting for some lwp to exit */
kcondvar_t p_holdlwps; /* process is waiting for its lwps */
/* to to be held. */
ushort_t p_pad1; /* unused */
uint_t p_flag; /* protected while set. */
/* flags defined below */
clock_t p_utime; /* user time, this process */
clock_t p_stime; /* system time, this process */
clock_t p_cutime; /* sum of children's user time */
clock_t p_cstime; /* sum of children's system time */
caddr_t *p_segacct; /* segment accounting info */
caddr_t p_brkbase; /* base address of heap */
size_t p_brksize; /* heap size in bytes */
/*
* Per process signal stuff.
*/
k_sigset_t p_sig; /* signals pending to this process */
k_sigset_t p_ignore; /* ignore when generated */
k_sigset_t p_siginfo; /* gets signal info with signal */
struct sigqueue *p_sigqueue; /* queued siginfo structures */
struct sigqhdr *p_sigqhdr; /* hdr to sigqueue structure pool */
struct sigqhdr *p_signhdr; /* hdr to signotify structure pool */
uchar_t p_stopsig; /* jobcontrol stop signal */
Kernel & Processes
struct proc (Solaris OS)
CS446/646 C. Papachristos
/*
* Special per-process flag when set will fix misaligned memory
* references.
*/
char p_fixalignment;
/*
* Per process lwp and kernel thread stuff
*/
id_t p_lwpid; /* most recently allocated lwpid */
int p_lwpcnt; /* number of lwps in this process */
int p_lwprcnt; /* number of not stopped lwps */
int p_lwpwait; /* number of lwps in lwp_wait() */
int p_zombcnt; /* number of zombie lwps */
int p_zomb_max; /* number of entries in p_zomb_tid */
id_t *p_zomb_tid; /* array of zombie lwpids */
kthread_t *p_tlist; /* circular list of threads */
/*
* /proc (process filesystem) debugger interface stuff.
*/
k_sigset_t p_sigmask; /* mask of traced signals (/proc) */
k_fltset_t p_fltmask; /* mask of traced faults (/proc) */
struct vnode *p_trace; /* pointer to primary /proc vnode */
struct vnode *p_plist; /* list of /proc vnodes for process */
kthread_t *p_agenttp; /* thread ptr for /proc agent lwp */
struct watched_area *p_warea; /* list of watched areas */
ulong_t p_nwarea; /* number of watched areas */
struct watched_page *p_wpage; /* remembered watched pages (vfork) */
int p_nwpage; /* number of watched pages (vfork) */
int p_mapcnt; /* number of active pr_mappage()s */
struct proc *p_rlink; /* linked list for server */
kcondvar_t p_srwchan_cv;
size_t p_stksize; /* process stack size in bytes */
/*
* Microstate accounting, resource usage, and real-time profiling
*/
hrtime_t p_mstart; /* hi-res process start time */
hrtime_t p_mterm; /* hi-res process termination time */
hrtime_t p_mlreal; /* elapsed time sum over defunct lwps */
hrtime_t p_acct[NMSTATES]; /* microstate sum over defunct lwps */
struct lrusage p_ru; /* lrusage sum over defunct lwps */
struct itimerval p_rprof_timer; /* ITIMER_REALPROF interval timer */
uintptr_t p_rprof_cyclic; /* ITIMER_REALPROF cyclic */
uint_t p_defunct; /* number of defunct lwps */
/*
* profiling. A lock is used in the event of multiple lwp's
* using the same profiling base/size.
*/
kmutex_t p_pflock; /* protects user profile arguments */
struct prof p_prof; /* profile arguments */
/*
* The user structure
*/
struct user p_user; /* (see sys/user.h) */
/*
* Doors.
*/
kthread_t *p_server_threads;
struct door_node *p_door_list; /* active doors */
struct door_node *p_unref_list;
kcondvar_t p_server_cv;
char p_unref_thread; /* unref thread created */
Kernel & Processes
struct proc (Solaris OS)
CS446/646 C. Papachristos
/*
* Kernel probes
*/
uchar_t p_tnf_flags;
/*
* C2 Security (C2_AUDIT)
*/
caddr_t p_audit_data; /* per process audit structure */
kthread_t *p_aslwptp; /* thread ptr representing "aslwp" */
#if defined(i386) || defined(__i386) || defined(__ia64)
/*
* LDT support.
*/
kmutex_t p_ldtlock; /* protects the following fields */
struct seg_desc *p_ldt; /* Pointer to private LDT */
struct seg_desc p_ldt_desc; /* segment descriptor for private LDT */
int p_ldtlimit; /* highest selector used */
#endif
size_t p_swrss; /* resident set size before last swap */
struct aio *p_aio; /* pointer to async I/O struct */
struct itimer **p_itimer; /* interval timers */
k_sigset_t p_notifsigs; /* signals in notification set */
kcondvar_t p_notifcv; /* notif cv to synchronize with aslwp */
timeout_id_t p_alarmid; /* alarm's timeout id */
uint_t p_sc_unblocked; /* number of unblocked threads */
struct vnode *p_sc_door; /* scheduler activations door */
caddr_t p_usrstack; /* top of the process stack */
uint_t p_stkprot; /* stack memory protection */
model_t p_model; /* data model determined at exec time */
struct lwpchan_data *p_lcp; /* lwpchan cache */
/*
* protects unmapping and initilization of robust locks.
*/
kmutex_t p_lcp_mutexinitlock;
utrap_handler_t *p_utraps; /* pointer to user trap handlers */
refstr_t *p_corefile; /* pattern for core file */
#if defined(__ia64)
caddr_t p_upstack; /* base of the upward-growing stack */
size_t p_upstksize; /* size of that stack, in bytes */
uchar_t p_isa; /* which instruction set is utilized */
#endif
void *p_rce; /* resource control extension data */
struct task *p_task; /* our containing task */
struct proc *p_taskprev; /* ptr to previous process in task */
struct proc *p_tasknext; /* ptr to next process in task */
int p_lwpdaemon; /* number of TP_DAEMON lwps */
int p_lwpdwait; /* number of daemons in lwp_wait() */
kthread_t **p_tidhash; /* tid (lwpid) lookup hash table */
struct sc_data *p_schedctl; /* available schedctl structures */
} proc_t;
Kernel & Processes
Process Execution State
A Process has an Execution State to indicate what it is doing
Running
Executing Instructions on a CPU
Ready
Waiting to be assigned to a CPU
Waiting
Waiting for an Event, e.g., I/O completion
CS446/646 C. Papachristos
Kernel & Processes
Transition of Process Execution State
As a Process executes, it moves from Execution State to Execution State
General
Execution State Graph:
CS446/646 C. Papachristos
Kernel & Processes
Transition of Process Execution State
As a Process executes, it moves from Execution State to Execution State
Linux
Execution State Graph:
CS446/646 C. Papachristos
Sleep
States
Stopped State
(via SIGNAL)
Kernel & Processes
(Execution) State Queues
How the OS keeps track of Processes
Simple 1st Idea:
Improvement:
CS446/646 C. Papachristos
Kernel & Processes
(Execution) State Queues
CS446/646 C. Papachristos
Note: There may be many Wait State Queues, one for each
type of Wait (Disk, Console, Timer, Network, etc.)
Kernel & Processes
Scheduling
How the OS determines which Process to run
Simplistic 1st Idea: Scan Process Table for first Runnable one
Better Idea: First-In First-Out (FIFO) Scheduling
Even Better: Priority Scheduling
CS446/646 C. Papachristos
Kernel & Processes
Process Dispatching Mechanism
OS Process Dispatching loop
CS446/646 C. Papachristos
WHILE TRUE:
Run Process for some time
Save Process State
Next Process = Schedule (Ready-State Processes)
Load next Process State
II. Context Switching
I. Regaining Control
Kernel & Processes
I. How to Regain Control
Cooperative Multitasking:
Processes voluntarily yield control back to OS
True Multitasking:
OS “Preempts” Processes by periodic Interrupts
CS446/646 C. Papachristos
Kernel & Processes
I. How to Regain Control
Preemption
Process Scheduling decision triggering
CS446/646 C. Papachristos
Note: Intended for use with a specific class Scheduling policies (i.e. Real-Time). Causes the calling Thread to relinquish the CPU. The calling Thread is moved to the end of the Queue for its Static Priority and a new Thread gets to run.
Kernel & Processes
II. How to Switch Context
Context Switching
Changing over the running Process
CS446/646 C. Papachristos
Kernel & Processes
II. How to Switch Context
Context Switching
Changing over the running Process
CS446/646 C. Papachristos
Kernel & Processes
II. How to Switch Context
Context Switching is very Machine-dependent. Typical things include:
Tricky:
CS446/646 C. Papachristos
Kernel & Processes
II. How to Switch Context
Context Switching has a non-negligible cost
Context Switching usually causes more CPU Cache Misses
CS446/646 C. Papachristos
Next Lecture Reading Preparation
Operating Systems – Three Easy Pieces (https://pages.cs.wisc.edu/~remzi/OSTEP/)
Virtualization
CS446/646 C. Papachristos
Process-related System Calls
Allow one Process to create another Child Process
A Process is created by another Process
Parent defines Resources and Privileges for its Children
After creating a Child Process
CS446/646 C. Papachristos
Process-related System Calls
Process Creation in Windows
1. Creates and initializes a new PCB
2. Creates and initializes a new Address Space
3. Loads the program specified by prog into the Address Space
4. Copies args into Memory allocated in Address Space
5. Initializes the saved hardware Context to start execution at main (or as specified)
6. Places the PCB on the Ready Queue
Note: Returns BOOL. If CreateProcess succeeds, it returns a PROCESS_INFORMATION structure that contains Handles and Identifiers for the new Process and its primary Thread. The Thread and Process Handles are created with full�access rights, although you can restrict access if you specify Security Descriptors.
CS446/646 C. Papachristos
CreateProcess( prog, // Module to load (e.g. "c:\\winnt\\notepad.exe“ or NULL – use command line)
argv[1], // Command line args
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
Process-related System Calls
Process Creation in Unix
1. Creates and initializes a new PCB
2. Creates a new Address Space
3. Initializes the Address Space with a copy of the Address Space of the Parent
4. Initializes the Kernel Resources to point to the Parent’s Resources (e.g. open Files)
5. Places the PCB on the Ready Queue
fork() returns twice:
(???)
Because if it’s successful, we now have 2 Processes
CS446/646 C. Papachristos
pid_t fork (void)
Process-related System Calls
Process Creation in Unix
CS446/646 C. Papachristos
pid_t fork (void)
Process-related System Calls
Process Creation in Unix
Expected program output ($ gcc –o fork_proc fork_proc.c && ./fork_proc)?
I’m the parent and my child’s pid is: 486
I’m the child of ./fork_proc and my pid is: 486
CS446/646 C. Papachristos
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char *name = argv[0];
int fork_retval = fork();
if (fork_retval == 0) {
printf("I’m the child of %s and my pid is: %d\n", name, getpid());
return 0;
} else {
printf("I’m the parent and my child’s pid is: %d\n", fork_retval);
return 0;
}
}
pid_t fork (void)
Process-related System Calls
Process Creation in Unix
CS446/646 C. Papachristos
pid_t fork (void)
fork_retval
fork_retval
fork_retval
fork_retval
fork_retval
fork_retval
Process-related System Calls
Process Creation in Unix
CS446/646 C. Papachristos
pid_t fork (void)
fork_retval
fork_retval
fork_retval
fork_retval
fork_retval
fork_retval
Process-related System Calls
Process Creation in Unix
Program output (continued)
$ ./fork_proc
My child is 486
Child of ./fork_proc is 486
$ ./fork_proc
Child of ./fork_proc is 486
My child is 486
Note: Notice possible change of output order between subsequent runs of the same executable
CS446/646 C. Papachristos
pid_t fork (void)
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char *name = argv[0];
int fork_retval = fork();
if (fork_retval == 0) {
printf("Child of %s is %d\n", name, getpid());
return 0;
} else {
printf("My child is %d\n", fork_retval);
return 0;
}
}
Process-related System Calls
Process Creation in Unix
Running a Program
v : Takes an argv array of C-strings populated with the Program, its Arguments/Flags, and a NULL-pointer at the end
e : Takes an envp array of C-strings populated Environment variables.
p : Inherits the Parent Process Environment.
execXX(…)
1. Stops the Program executing under the current Process
2. Loads the new Program prog into the calling Process’ Address Space
3. Initializes Hardware Context and Args for the new Program
4. Places the PCB onto the Ready Queue
Note: It does NOT create a new Process. “… it replaces the entire current Process with a new Program image”.� It loads the Program into the current Process’ Address Space and runs it from the entry point.
(Also, in PintOS, exec is more like a combined fork/exec)
CS446/646 C. Papachristos
int execv(char *prog, char *const argv[]);
int execve(const char *prog, char *const argv[], char *const envp[]);
int execvp(const char *prog, char *const argv[]);
Process-related System Calls
Process Creation in Unix
Most calls to fork() will be followed by execXX(…)
Very useful when
Example: Web Server
CS446/646 C. Papachristos
int server_sock = socket() … bind() … listen() …
while (1) {
// Accept connection request from client in addr
int client_sock = accept(server_sock, addr, addrlen);
// accept() returned: incoming connection - Create a Child Process
if ((fork_retval = fork()) == 0) { // Child Process
close(server_sock);
// Use client_sock (e.g. send() client a handshake msg)
} else { // Parent Process
// back to listening for more incoming, no need to wait on Child
}
}
Note 1: The accept() Syscall creates a new Socket�Descriptor with the same properties as server_sock and returns it to the caller. If the queue has no pending connection requests, accept() Blocks the caller unless server_sock is in Nonblocking mode. If no connection requests are queued and server_sock is in Nonblocking mode, accept() returns -1 and sets the error code to EWOULDBLOCK.
Note 2: The argument server_sock is a Socket that has been created with socket(), bound to a local Address with bind(), and is listening for Connections after a listen().
Process-related System Calls
Process Creation in Unix
Example: Simple Shell
CS446/646 C. Papachristos
pid_t pid; char **av;
/* ... main loop: */
for (;;) {
parseInput (&av, stdin); //read shell commands from stdin
switch (fork_retval = fork ()) {
case -1: //Parent Process – fork error
perror ("fork error"); break;
case 0: //Child Process
execProc (); break;
default: //Parent Process
waitpid (fork_retval, NULL, 0); break;
}
}
/* ... rest of main */
void execProc () { //inside Child Process
execvp (av[0], av);
perror (av[0]);
_exit (1);
}
$ gcc -o simpleshell simpleshell.c
$ ./simpleshell
$ date
Wed Sep 6 09:20:53 PDT 2023
$ /usr/bin/gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
…
Process-related System Calls
Process Creation in Unix
Majority of calls to fork() are followed by execXX(…)
Very useful when
Real win is in the simplicity of its interface
CS446/646 C. Papachristos
Process-related System Calls
Process Creation in Unix
Example: Simple Shell with Redirection
CS446/646 C. Papachristos
void execProc () { //inside Child Process
/*...handle case for infile→fd:0...*/
if (infile) { /* set non-NULL when "cmd < infile" */
int fd_in;
if ((fd_in = open (infile, O_RDONLY)) < 0) {
perror (infile);
_exit (1);
}
if (fd_in != 0) {
dup2 (fd_in, STDIN_FILENO);
close (fd_in); //don’t keep around extra
} //reference to opened infile
}
/*...handle case for outfile→fd:1...*/
if (outfile) { ... }
/*...handle case for errfile→fd:2...*/
if (errfile) { ... }
execvp (av[0], av);
perror (av[0]);
_exit (1);
}
$ gcc -o redirshell redirshell.c
$ ./redirshell
$ ls > list.txt
$ sort < list.txt > sorted_list.txt
$ cat sorted_list.txt
a.c
b.c
cs446.txt
…
Note:
0: STDIN_FILENO
1: STDOUT_FILENO
2: STDERR_FILENO
Note:
System Call – Duplicate File Descriptor
int dup2(int oldfd, int newfd);
(In short:) Makes newfd be the copy of oldfd, closing newfd first if necessary.
Process-related System Calls
Process Creation in Unix
Why does Windows use CreateProcess while Unix uses fork/execXX?
CS446/646 C. Papachristos
Process-related System Calls
Process (Normal) Termination
In Unix: exit (int status) (In Windows: ExitProcess (int status))
Frees Resources and terminates “normally”, returns status & 0xFF to Parent wait()
1. Terminate all Threads of calling Process (more in Threads Lecture …)
2. Close open Files, Network Connections
3. Allocated Memory (mark Virtual Memory Pages as Free)
4. Remove PCB from Kernel data structures, delete
Note: All functions registered with atexit() and on_exit() are called, in the reverse order of their registration. … All open stdio streams are flushed and closed. Files created by tmpfile() are removed.
exit() is a System Call, i.e. a Process does not just simply clean up after itself
CS446/646 C. Papachristos
Process-related System Calls
Process (Immediate) Termination
In Unix: _exit (int status)
Frees resources and terminates “immediately”, returns status & 0xFF to Parent wait()
Note: Terminates the calling Process “immediately”. Any open File Descriptors belonging to the calling Process are closed; any Children of the calling Process are inherited by Process 1, init, and the calling Process’s Parent is sent a SIGCHLD Signal.
I.e. calling the “normal” exit() from a forked Child that hasn’t successfully exec’d something (to replace the original Process image it inherits), will interfere with the Parent Process’ external data (Files) via calling its atexit() handlers, calling its Signal handlers, and/or flushing Buffers (i.e. print out whatever exists in stdio of the newly forked Child Process which is an exact User Space duplicate of the Parent – “double-flushing”)
Rule-of-Thumb:
CS446/646 C. Papachristos
Process-related System Calls
Waiting on a Process
In Unix: pid_t wait (int *status) (In Windows: WaitForSingleObject(eHandle,millis))
pid_t waitpid (pid_t pid, int *status, int options)
Return value of wait/waitpid :
CS446/646 C. Papachristos
Note:
pid > 0: wait for the Child whose Process ID is equal to the value of pid.
pid = 0: wait for any Child Process whose Process Group ID is equal to that of the calling Process.
pid = -1: wait for any Child Process.
pid < 0: wait for any Child Process whose Process Group ID is equal to the absolute value of pid.
Process-related System Calls
Waiting on a Process
The purpose of the wait() Syscall is to allow the Child Process to report a status back to the Parent Process
Zombie Process: Child that terminates, but has not been wait()ed for yet (by the/a Parent). The Kernel maintains a minimal set of information about the zombie (PID, termination status, resource usage information) in order to allow the Parent to later perform a wait() to obtain information about the Child. As long as a Zombie is not removed from the system via a wait(), it will consume a slot in the kernel Process Table, and if this table fills, it will not be possible to create further Processes. If a Parent Process terminates, then its Zombie Children (if any) are adopted by init(), which automatically performs a wait() to remove the Zombies.
Note: Every Process spawned after init has a Parent Process
CS446/646 C. Papachristos
A Process Tree
Note: Usual convention is that the Parent that forked the Children waits on�them, because typically they are doing part of the job it was expected to do.
Process-related System Calls
Waiting on a Process
The purpose of the wait() Syscall is to allow the Child Process to report a status back to the Parent Process
Orphan Process:�When a Parent Process dies before a Child Process
CS446/646 C. Papachristos
Note: Usual convention is that the Parent that forked the Children waits on�them, because typically they are doing part of the job it was expected to do.
ping -D localhost >/dev/null 2>&1 & # Terminal 1: Start looping ping as daemon (background)
pstree -p # Terminal 2: Find PID of ping’s shell parent process
kill –SIGTERM [PING_PARENT_SHELL_PID] # Terminal 2: Kill ping’s shell parent process (T1 dies)
pstree –p # see how ping has been reparented to systemd (init)
Process-related System Calls
Process Miscellanea
CS446/646 C. Papachristos
Next Lecture Reading Preparation
Operating Systems – Three Easy Pieces (https://pages.cs.wisc.edu/~remzi/OSTEP/)
Intro
Concurrency
CS446/646 C. Papachristos
Time for Questions !
CS-446/646
CS446/646 C. Papachristos