Linux Process Management & Signals
-
Upload
sanjay-sahai -
Category
Documents
-
view
18 -
download
1
description
Transcript of Linux Process Management & Signals
Linux Process Management &
Signals
Gaurav Verma
Assistant Professor
Department of Electronics and Communication Engineering
Jaypee Institute of Information and Technology
Sector-62, Noida, Uttar Pradesh, India
2
Process Management
Processes
What is a Process?
Ans: A Program in execution is called a “Process”.
Importance Of Process In Operating System:
A Process needs certain resources – including CPU time,
memory, files and I/O devices to accomplish a task. These
resources are either given to the process when it is created
or allocated to it while it is running.
A Process is the unit of work in most systems. System
consist of a collection of processes. Operating System
processes execute system code, and user processes executes
user code. All these processes executes concurrently.
3
4
Linux Process Management
Linux is a multitasking system
Multiple programs can be executed at the same
time
Ultimately, a program needs to be executed by a
CPU
If there is only one CPU, how multiple programs
can be executed at the same time?
By time sharing
That is, all programs are claimed to be executing.
In fact, most of them are waiting for the CPU
5
A program that is claimed to be executing is
called a process
For a multitasking system, a process has at least
the following three states:
Ready Running
Sleeping
Start
execution Finish
execution
6
Ready state
– All processes that are ready to execute but without
the CPU are at the ready state
– If there is only 1 CPU in the system, all processes
except one are at the ready state
Running state
– The process that actually possesses the CPU is at the
running state
– If there is only 1 CPU in the system, at most there is
only one process is at the running state
Sleeping state
– The process that is waiting for other resources, e.g.
I/O, is at the sleeping state
7
Processes will alternatively get into the CPU one after the
other (called the round robin scheme)
A process will be “in” a CPU for a very short time (quantum)
– For Linux, each quantum is about 100msec
At the time that a process is selected to be “in” the CPU
– It goes from ready state to running state
After that, it will be swapped out
– It goes from running state back to ready state
Or it may due to the waiting of an I/O device, e.g. mouse
– It goes from running state to sleeping state
When obtaining the required resource
– It goes from sleeping state to ready state
8
The mechanism to determine which process should “get
into” the CPU is called Process scheduling
For example,
a -> 10
b -> 0
c -> a+b
b -> c
c -> a+b
b -> c
c -> a+b
b -> c
c -> a+b
b -> c
c -> a+b
b -> c
Print out b
Set variable a to 10
Set variable b to 0
Set variable c to a+b
Repeat 5 times the following
{
Set variable b to c
}
Print out the value of b
Program A Actual sequence of operations
9
Set variable d to 0
Repeat 5 times the following
{
Ask user to enter variable e
Set variable f = d+e
Set variable d = f
}
Print out the value of d
d -> 0
User -> e
f -> d+e
d -> f
User -> e
f -> d+e
d -> f
User -> e
f -> d+e
d -> f
User -> e
f -> d+e
d -> f
User -> e
f -> d+e
d -> f
Print out d
Program B
Actual sequence of operations
10
a -> 10
b -> 0
c -> a+b
b -> c
c -> a+b
d -> 0
User -> e
b -> c
c -> a+b
b -> c
c -> a+b
b -> c
f -> d+e
d -> f
User -> e
c -> a+b
b -> c
Print out b
f -> d+e
d -> f
User -> e
f -> d+e
d -> f
User -> e
f -> d+e
d -> f
User -> e
f -> d+e
d -> f
Print out d
Program A and B will be at the running state alternatively,
depends on the quantum size and the availability of the
required resource
Quantum
end
Waiting for
user input
Quantum
end
Waiting for
user input
Program
A
finishes
Program
B
finishes
Operating System Responsibilities:
The Operating System is responsible for the
following activities in connection with the Process
Management:
• Creating and deleting both the user and system
processes
• Suspending and resuming processes
• Providing mechanisms for process synchronization
• Providing mechanisms for process communication
• Providing mechanism for deadlock handling 11
Structure of a Process In Memory
Address space the set of
accessible addresses + state
associated with them:
For a 32-bit processor there are
232 = 4 billion addresses
What happens when you read or
write to an address?
Perhaps Nothing
Perhaps acts like regular memory
Perhaps ignores writes
Perhaps causes I/O operation
(Memory-mapped I/O)
Perhaps causes exception (fault)
Program A
ddre
ss Spa
ce
12
Process stack:
It contains the temporary data such as function parameters, local variables
and return addresses.
Heap:
which is memory that is dynamically allocated during process run time.
Data Section:
It contains global variables.
Text Section:
A Process is more than the program code, which sometimes known as
the “Text Section”.
13
Providing Illusion of Separate Address Space: Load new Translation
Map on Switch
Prog 1 Virtual Address Space 1
Prog 2 Virtual Address Space 2
Code
Data
Heap
Stack
Code
Data
Heap
Stack
Data 2
Stack 1
Heap 1
OS heap &
Stacks
Code 1
Stack 2
Data 1
Heap 2
Code 2
OS code
OS data Translation Map 1 Translation Map 2
Physical Address Space 14
Process Control Block (PCB)
Information associated with each process
Process state
Program counter
CPU registers
CPU scheduling information
Memory-management information
Accounting information
I/O status information
15
Process Control Block (PCB):
Each process is represented in the operating system by a “Process
Control Block (PCB)” also called as “Task Control Block”.
Process State:
The state may be new, ready, running, waiting, halted, and so on.
Program Counter:
The counter indicates the address of the next instruction to be executed for this process.
CPU Registers:
Depending on the computer architecture, the registers may vary in
number and type. They include accumulators, index registers, stack
pointers and general purpose registers.
16
Process Creation
Parent process create children processes, which, in turn create
other processes, forming a tree of processes
Generally, process identified and managed via a process identifier
(pid)
Resource sharing
Parent and children share all resources
Children share subset of parent’s resources
Execution
Parent and children execute concurrently
Parent waits until children terminate
17
The Process Table
The Linux process table is like a data structure describing all of the
processes that are currently loaded with, for example, their PID,
status, and command string, the sort of information output by ps.
The operating system manages processes using their PIDs, and they
are used as an index into the process table. The table is of limited
size, so the number of processes a system will support is limited.
Early UNIX systems were limited to 256 processes.
More modern implementations have relaxed this restriction
considerably and may be limited only by the memory available to
construct a process table entry.
18
19
The processes of a system can
be seen by using the command
ps
Terminal pts/0 has the editor vi running
Terminal pts/1 is
executing ps to see
the processes of both
terminals
Viewing Processes
20
PID TTY STAT TIME COMMAND
14748 pts/1 S 0:00 –bash
1 pts/0 S 0:00 –bash
14974 pts/0 S 0:00 vi test1.txt
14876 pts/1 R 0:00 ps …
Process ID Terminal
name
State:
S – Sleeping
(waiting for input)
R – Running
How much time the
process is continuously
executing
Each process is allocated a unique number, called a process identifier or PID. This is usually
a positive integer between 2 and 32,768. When a process is started, the next unused
number in sequence is chosen and the numbers restart at 2 so that they wrap around.
The number 1 is typically reserved for the special init process, which manages other
processes.
21
For the example above, both bash processes,
which are the shell of both terminals, are
waiting for the input of user. They must be in
the sleeping state
The vi process, which is an editor, is also
waiting for the input of user. Hence it is also in
sleeping state
When ps reporting the processes in the
system, it is the only process that is running.
Hence it is in running state
22
A process can be forced to terminate by using
the command kill -9 PID
The vi process is terminated by using the command
kill -9 14874
Init process
In general, each process is started by another process known as
its parent process.
A process so started is known as a child process.
When Linux starts, it runs a single program, the prime ancestor
and process number 1, init. This is, if you like, the operating
system process manager and the grandparent of all processes.
Other system processes we’ll meet soon are started by init or by
other processes started by init.
23
Starting New Processes
We can cause a program to run from inside another program
and thereby create a new process by using the system library
function.
#include <stdlib.h>
int system (const char *string);
24
#include <stdlib.h>
#include <stdio.h>
int main()
{
printf(“Running ps with system\n”);
system(“ps -ax”);
printf(“Done.\n”);
exit(0);
}
Duplicating a Process Image To use processes to perform more than one function at a time, we can either use threads
or create an entirely separate process from within a program. We can create a new process
by calling fork. This system call duplicates the current process, creating a new entry in the
process table with many of the same attributes as the current process. The new process is
almost identical to the original, executing the same code but with its own data space,
environment, and file descriptors.
If fork fails, it returns -1. This is commonly due to a
limit on the number of child processes that a parent
may have in the system. pid_t new_pid;
new_pid = fork();
switch(new_pid)
{
case -1 : /* Error */
break;
case 0 : /* We are child */
break;
default : /* We are parent */
break;}
*Parent process return
the shell before
completion of child
process*
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t pid;
char *message;
int n;
printf(“fork program starting\n”);
pid = fork();
switch(pid){
case -1:
printf(“fork failed”);
exit(1);
case 0:
message = “This is the child”;
n = 5;
break;
default:
message = “This is the parent”;
n = 3;
break;
}
for(; n > 0; n--) {
puts(message);
sleep(1);}
exit(0);}
26
Waiting for a process the parent process wait until the child finishes before continuing
by calling wait.
# include <sys/types.h>
# include <sys/wait.h>
pid_t wait(int *stat_loc);
The wait system call causes a parent process to pause until one of
its child processes is stopped.
The call returns the PID of the child process. This will normally be
a child process that has terminated. The status information allows
the parent process to determine the exit status of the child
process, that is, the value returned from main or passed to exit. If
stat_loc is not a null pointer, the status information will be
written to the location to which it points. 27
Exit status
We can interpret the status information using macros defined in sys/wait.h. These include Macro Definition
WIFEXITED( stat_val) ; Nonzero if the child is terminated normally.
WEXITSTATUS( stat_val) ; If WIFEXITED is nonzero, this returns child exit code.
WIFSIGNALED( stat_val) ; Nonzero if the child is terminated on an uncaught signal.
WTERMSIG( stat_val) ; If WIFSIGNALED is nonzero, this returns a signal number.
WIFSTOPPED( stat_val) ; Nonzero if the child has stopped.
WSTOPSIG( stat_val); If WIFSTOPPED is nonzero, this returns a signal number.
28
Zombie Processes Using fork to create processes can be very useful, but you must keep track of child processes.
When a child process terminates, an association with its parent survives until the parent in
turn either terminates normally or calls wait. The child process entry in the process table is
therefore not freed up immediately. Although no longer active, the child process is still in the
system because its exit code needs to be stored in case the parent subsequently calls wait. It
becomes what is known as defunct, or a zombie process.
We can see a zombie process being created if we change the number of messages in the fork example
program. If the child prints fewer messages than the parent, it will finish first and will exist as a
zombie until the parent has finished. switch(pid)
{
case -1:
perror(“fork failed”);
exit(1);
case 0:
message = “This is the child”;
n = 3;
break;
default:
message = “This is the
parent”;
n = 5;
break;}
If we run the program & and then call the ps program after the child has
finished but before the parent has finished, we’ll see a line such as this. (Some
systems may say <zombie>rather than <defunct>.)
$ ps –al
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
000 S 500 1603 1262 0 75 0 - 313 schedu pts/1 00:00:00 fork2
003 Z 500 1604 1603 0 75 0 - 0 do_exi pts/1 00:00:00 fork2 <defunct>
000 R 500 1605 1262 0 81 0 - 781 - pts/1 00:00:00 ps
What Are Signals?
Signals, to be short, are various notifications sent to a process in
order to notify it of various "important" events. By their nature,
they interrupt whatever the process is doing at this minute, and
force it to handle them immediately. Each signal has an integer
number that represents it (1, 2 and so on), as well as a symbolic
name that is usually defined in the file /usr/include/signal.h
Use the command 'kill -l' to see a list of signals supported by
your system).
30
Signal cont…
Each signal may have a signal handler, which is a function that
gets called when the process receives that signal. The function is
called in "asynchronous mode", meaning that no where in your
program you have code that calls this function directly.
Instead, when the signal is sent to the process, the operating
system stops the execution of the process, and "forces" it to call
the signal handler function. When that signal handler function
returns, the process continues execution from wherever it
happened to be before the signal was received, as if this
interruption never occurred.
31
Signals v/s interrupts
The difference is that while interrupts are sent to the
operating system by the hardware, signals are sent to the
process by the operating system, or by other processes. Note
that signals have nothing to do with software interrupts,
which are still sent by the hardware (the CPU itself, in this
case).
32
What Are Signals Used For?
Signals are usually used by the operating system to notify
processes that some event occurred, without these processes
needing to poll for the event. Signals should then be handled,
rather then used to create an event notification mechanism for
a specific application.
33
Sending Signals To Processes
Sending Signals Using The Keyboard
Ctrl-C
Ctrl-Z
Ctrl-\
Sending Signals From The Command Line
$kill
Sending Signals Using System Calls
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
pid_t my_pid = getpid();
kill(my_pid, SIGSTOP);
34
Catching Signals - Signal Handlers
Catchable And Non-Catchable Signals
Most signals may be caught by the process, but there are a
few signals that the process cannot catch, and cause the
process to terminate.
SIGKILL & SIGSTOP
35
Default Signal Handlers
If you install no signal handlers of your own , the runtime
environment sets up a set of default signal handlers for your
program.
For example, the default signal handler for the TERM signal calls
the exit() system call.
The default handler for the ABRT is to dump the process's
memory image into a file named 'core' in the process's current
directory, and then exit.
36
Installing Signal Handlers
The signal() System Call The signal() system call is used to set a signal handler for a single signal type. signal() accepts a signal
number and a pointer to a signal handler function, and sets that handler to accept the given signal.
#include <stdio.h>
#include <unistd.h>
#include <sys/ types.h>
#include <signal.h>
void catch_int( int signum)
{
signal(SIGINT, catch_int);
printf("Don't do that");
fflush( stdout);
}
main()
{
(void)signal(SIGINT, catch_int);
while(1);
} 37
Pre-defined Signal Handlers
For our convenience, there are two pre-defined signal handler functions that we can use, instead of writing our own: SIG_IGN and SIG_DFL.
SIG_IGN:
Causes the process to ignore the specified signal. For example, in order to ignore Ctrl-C completely (useful for programs that must NOT be interrupted in the middle, or in critical sections), write this: signal(SIGINT, SIG_IGN);
SIG_DFL:
Causes the system to set the default signal handler for the given signal (i.e. the same handler the system would have assigned for the signal when the process started running): signal(SIGTSTP, SIG_DFL);
38