signal
Function :
Posix way to establish the disposition of a
signal is to call the sigaction
function. However this is complicated at one argument to the function is a
structure that we must allocate and fill in. An easier way to set the
disposition for a signal is to call the signal
function. The first argument is the signal
name and the second arguments is the pointer
to a function or one of the constants SIG_IGN
or SIG_DFE.
Normally, the define our own signal function that just calls the Posix sigaction.
line 2-3 call to the function when a signal
occurs. It has pointer to signal handling function as the second argument
Line 6: Set Handler : The sa_handler member of
the sigaction structure is set to the func argument
Line 7: Set signal mask to handler: POSIX
allows us to specify a set of signals that will be blocked when our signal
handler is called. Any signal that is blocked cannot be delivered to the
process. We set the sa_mask member to the empty set, which means that no
additional signals are blocked while our signal handler is running Posix
guarantees that he signal being caught is always blocked while its handler is
executing
Line 8 – 17: An optional flag SA_RESTART, if it
is set, a system call interrupted by this signal will automatically restarted
by the kernal.
Line 18 – 20: The function sigaction is called
and then return the old action for the signal as the return value of the signal
function.
Posix Signal semantics:
1. Once a signal handler is installed, it remains
installed.
2. While a signal handler is executing, the signal
being delivered is blocked. Further any additional signals that were specified
in the sa_mask signal set passed to sigaction when the handler was installed
are also blocked . When the sa_mask
is set to empty set, no additional signals are blocked other than the signal
being caught.
3. If a signal is being generated more times while
it is blocked, it is normally delivered
only one time
after the signal is unblocked.
4. It is possible to selectively block and unblock a set of signals
using the sigprocmask function. This protects a critical region of code by
providing certain signals from being caught while the region of code is
executing.
Handling SIGCHLD signals:
A zombie
is a process that ha terminated whose parent is still running, but has not yet
waited for its child processes. This will result in the resources occupied by
the terminated process not returned to the system. If there are a lot of
zombies in the system the system resources may run out.
The
purpose of the zombie state is to maintain information about the child for the
parent to fetch at some time later. The information are : the process ID of the
child, its termination status and information on the resource utilization of
the child (CPU time, memory etc). If a process terminates, and the process has
children in the zombie state. The parent process ID of all the zombie children
is set to 1 (the init process), which will inherit the children and clean them
up.
The
zombie are not desired to be left. They take up space in the kernal and
eventually we can run out of process. Whenever we fork children, we must wait,
for them to prevent them from becoming zombies.
When a
child terminates, the kernal generates a SGICHLD signal for the parent. The
parent process should catch the signal and take an appropriate action. If the
signal is not caught, the default action of this signal is to be ignored.
To
handle a zombie, the parent process establishes a signal handler to catch
SIGCHLD signal. The handler then invokes the function wait() or waitpid () to
wait for a terminated child process and free all the system resources occupied
by the process.
To do
this we establish a signal handler called SIGCHLD and within the handler, we
call wait. The signal handler is established by adding function call
Signal(SIGCHLD, sig_chld)
Interrupted
System Calls:
There are certain system calls in the Client
Server communication that are blocked while waiting for input. It can be seen
that in the case of echo client server programme, in the server programme, the
function accept () is blocked while waiting for the call from a client. This
condition is called slow system call . This can also occur in case of
functional calls such as read(), write (), select(), open () etc. Under such
condition, when a SIGCHLD is delivered on termination of a process, the sig_chld
function executes (the signal handler for SIGCHLD), wait function fetches the
child‘s pid and termination status. The signal handler then returns.
But as
the signal was caught by the parent while parent was blocked in a slow system
call (accept), the kernal causes the accept to return an error of EINTR
(interrupted system call). The parent does not handle this error, so it aborts.
This is a potential problem which all slow system call (read, write, open,
select etc) face whenever they catch any signal. This is undesirable.
In case of Solaris 2.5, the signal function
provided in the C library does not cause an interrupted system call to be
automatically restarted by the kernal. That is SA_RESTART flag that is set in
signal function is not set by the signal function in the system library. Where
as some other systems like, 4.4 BSD using the library version of signal
function, the kernal restarts the interrupted system call and accept does not
return an error.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.