Overview of today’s lecture
Re-view of the previous lecture
Process management models and state machines
(cont’d from the previous lecture)
What is in a process control block
Operating system calls for process management in
UNIX family of systems
Example programs invoking OS services for process
management
Re-cap of lecture
Suspending Processes
May suspend a process by swapping part or all of it to disk
Most useful if we are waiting for an event that will not arrive soon
(printer, keyboard)
If not done well, can slow system down by increasing disk I/O activity
State Transition Diagram
Key States:
Ready – In memory, ready to execute
Blocked – In memory, waiting for an event
Blocked Suspend – On disk, waiting for an event
Ready Suspend – On disk, ready to execute
Unix SVR4 Processes
Uses 9 processes states
Preempted and Ready to run, in memory are nearly identical
A process may be preempted for a higher-priority process at the
end of a system call
Zombie – Saves information to be passed to the parent of this process
Process 0 – Swapper, created at boot
Process 1 – Init, creates other processes
Modes of Execution
User mode
Less-privileged mode
User programs typically execute in this mode
System mode, control mode, or kernel mode
More-privileged mode
Kernel of the operating system
Operating System Control Structures
Information about the current status of each process
and resource
Tables are constructed for each entity the operating
system manages
Memory Tables
Allocation of main memory to processes
Allocation of secondary memory to processes
Protection attributes for access to shared memory
regions
Information needed to manage virtual memory
I/O Tables
I/O device is available or assigned
Status of I/O operation
Location in main memory being used as the
source or destination of the I/O transfer
File Tables
Existence of files
Location on secondary memory
Current Status
Attributes
Sometimes this information is maintained by
a file management system
Process Control Block
Process identification
Identifiers
Numeric identifiers that may be stored with the
process control block include
Identifier of this process
Identifier of the process that created this process
(parent process)
User identifier
Process Control Block
Processor State Information
User-Visible Registers
A user-visible register is one that may be
referenced by means of the machine language
that the processor executes while in user mode.
Typically, there are from 8 to 32 of these
registers, although some RISC implementations
have over 100.
Process Control Block
Processor State Information
Control and Status Registers
These are a variety of processor registers that are
employed to control the operation of the processor.
These include
Program counter: Contains the address of the next
instruction to be fetched
Condition codes: Result of the most recent arithmetic or
logical operation (e.g., sign, zero, carry, equal, overflow)
Status information: Includes interrupt enabled/disabled
flags, execution mode
Process Control Block
Processor State Information
Stack Pointers
Each process has one or more last-in-first-out (LIFO)
system stacks associated with it. A stack is used to store
parameters and calling addresses for procedure and
system calls. The stack pointer points to the top of the
stack.
Process Control Block
Process Control Information
Scheduling and State Information
This is information that is needed by the operating system to perform
its scheduling function. Typical items of information:
Process state: defines the readiness of the process to be
scheduled for execution (e.g., running, ready, waiting, halted).
Priority:
One or more fields may be used to describe the
scheduling priority of the process. In some systems, several values
are required (e.g., default, current, highest-allowable)
Scheduling-related
information: This will depend on the
scheduling algorithm used. Examples are the amount of time that the
process has been waiting and the amount of time that the process
executed the last time it was running.
Event: Identity of event the process is awaiting before it can be
resumed
Process Control Block
Process Control Information
Data Structuring
A process may be linked to other process in a queue,
ring, or some other structure. For example, all processes
in a waiting state for a particular priority level may be
linked in a queue. A process may exhibit a parent-child
(creator-created) relationship with another process. The
process control block may contain pointers to other
processes to support these structures.
Process Control Block
Process Control Information
Inter-process Communication
Various flags, signals, and messages may be associated with
communication between two independent processes. Some or
all of this information may be maintained in the process control
block.
Process Privileges
Processes are granted privileges in terms of the memory that
may be accessed and the types of instructions that may be
executed. In addition, privileges may apply to the use of system
utilities and services.
fork: Creating new processes
int fork(void)
creates a new process (child process) that is identical to the
calling process (parent process)
returns 0 to the child process
returns child’s pid to the parent process
if (fork() == 0) {
printf("hello from child\n");
} else {
printf("hello from parent\n");
}
Fork is interesting
(and often confusing)
because it is called
once but returns twice
Fork Example #1
Key Points
Parent and child both run same code
Distinguish parent from child by return value from fork
Start with same state, but each has private copy
Including shared output file descriptor
Relative ordering of their print statements undefined
void fork1()
{
int x = 1;
pid_t pid = fork();
if (pid == 0) {
printf("Child has x = %d\n", ++x);
} else {
printf("Parent has x = %d\n", --x);
}
printf("Bye from process %d with x = %d\n", getpid(), x);
}
Fork Example #2
Key Points
Both parent and child can continue forking
void fork2()
{
printf("L0\n");
fork();
printf("L1\n");
fork();
printf("Bye\n");
}
L0
L1
Bye
Bye
L1
Bye
Bye
Fork Example #3
Key Points
Both parent and child can continue forking
void fork3()
{
printf("L0\n");
fork();
printf("L1\n");
fork();
printf("L2\n");
fork();
printf("Bye\n");
}
L1
L0
L1
L2
Bye
Bye
L2
Bye
Bye
L2
Bye
Bye
L2
Bye
Bye
Fork Example #4
Key Points
Both parent and child can continue forking
void fork4()
{
printf("L0\n");
if (fork() != 0) {
printf("L1\n");
if (fork() != 0) {
printf("L2\n");
fork();
}
}
printf("Bye\n");
}
Bye
Bye
L0
L1
L2
Bye
Bye
Fork Example #5
Key Points
Both parent and child can continue forking
void fork5()
{
printf("L0\n");
if (fork() == 0) {
printf("L1\n");
if (fork() == 0) {
printf("L2\n");
fork();
}
}
printf("Bye\n");
}
Bye
L2
L1
L0
Bye
Bye
Bye
exit: Destroying Process
void exit(int status)
exits a process
Normally return with status 0
atexit() registers functions to be executed upon exit
void cleanup(void) {
printf("cleaning up\n");
}
void fork6() {
atexit(cleanup);
fork();
exit(0);
}
Zombies
Idea
Reaping
When process terminates, still consumes system resources
Various tables maintained by OS
Called a “zombie”
Living corpse, half alive and half dead
Performed by parent on terminated child
Parent is given exit status information
Kernel discards process
What if Parent Doesn’t Reap?
If any parent terminates without reaping a child, then child will be
reaped by init process
Only need explicit reaping for long-running processes
E.g., shells and servers
Zombie
Example
void fork7()
{
if (fork() == 0) {
/* Child */
printf("Terminating Child, PID =
%d\n",
getpid());
exit(0);
} else {
printf("Running Parent, PID = %d\n",
getpid());
while (1)
; /* Infinite loop */
}
}
linux> ./forks 7 &
[1] 6639
Running Parent, PID = 6639
Terminating Child, PID = 6640
linux> ps
PID TTY
TIME CMD
6585 ttyp9
00:00:00 tcsh
6639 ttyp9
00:00:03 forks
6640 ttyp9
00:00:00 forks <defunct>
6641 ttyp9
00:00:00 ps
linux> kill 6639
[1]
Terminated
linux> ps
PID TTY
TIME CMD
6585 ttyp9
00:00:00 tcsh
6642 ttyp9
00:00:00 ps
ps shows child
process as “defunct”
Killing parent allows
child to be reaped
Nonterminating
Child
Example
linux> ./forks 8
Terminating Parent, PID = 6675
Running Child, PID = 6676
linux> ps
PID TTY
TIME CMD
6585 ttyp9
00:00:00 tcsh
6676 ttyp9
00:00:06 forks
6677 ttyp9
00:00:00 ps
linux> kill 6676
linux> ps
PID TTY
TIME CMD
6585 ttyp9
00:00:00 tcsh
6678 ttyp9
00:00:00 ps
void fork8()
{
if (fork() == 0) {
/* Child */
printf("Running Child, PID = %d\n",
getpid());
while (1)
; /* Infinite loop */
} else {
printf("Terminating Parent, PID =
%d\n", getpid());
exit(0);
}
}
Child process still active
even though parent has
terminated
Must kill explicitly, or else
will keep running
indefinitely