Signals in C language
Prerequisite : Fork system call, Wait call
A signal could be a software package generated interrupt that's sent to a process by the OS attributable to once user press ctrl-c or another method tell one thing to the present method.
There area unit fix set of signals which will be sent to a method. signal area unit known by integers.
Signal variety have symbolic names. as an example SIGCHLD is variety of the signal sent to the parent method once kid terminates.
Examples:
#define SIGHUP 1 /*
Hangup the process */
#define SIGINT 2 /*
Interrupt the process */
#define SIGQUIT 3 /* Quit the process */
#define SIGILL 4 /*
Illegal instruction. */
#define SIGTRAP 5 /* Trace trap. */
#define SIGABRT 6 /* Abort. */
ü OS Structures for Signals
For each method, the operating system maintains two integers
with the bits resembling a signal numbers.
The two integers keep track of: unfinished signals and
blocked signals
Example :
In the example below, the intelligence operation ( = 2)
signal is blocked and no signals are unfinished.
Pending Signals :
31 30
29 28 ...... 3 2
1 0
0
|
0
|
0
|
0
|
……
|
0
|
0
|
0
|
0
|
Blocked Signals :
31 30 29 28 ...... 3 2 1 0
0
|
0
|
0
|
0
|
……
|
0
|
0
|
0
|
0
|
A signal is distributed to a process setting the
corresponding bit within the unfinished signals number for the process. anytime
the OS selects a method to be run on a processor, the unfinished and blocked
integers ar checked. If no signals ar unfinished, the method is restarted
commonly and continues death penalty at its next instruction.
If 1 or additional signals ar unfinished, however all is
blocked, the method is also restarted commonly however with the signals still
marked as unfinished. If one or additional signals ar unfinished and NOT
blocked, the OS executes the routines within the process’s code to handle the
signals.
Default Signal Handlers
There are many default signal handler routines. every
signal is related to one amongst these default handler routine. the various
default handler routines generally have one amongst the subsequent actions:
Ø Ign: Ignore the signal; i.e., do
nothing, simply come back
Ø Term: terminate the method
Ø Cont: unblock a stopped method
Ø Stop: block the method
// default Signal Handler
#include<stdio.h>
#include<signal.h>
int main()
{
signal(SIGINT, handle_sigint);
while (1)
{
printf(“hello world\n”);
sleep(1);
}
return 0;
}
Output: Print hello world infinite times. If user presses ctrl-c to terminate the process because of SIGINT signal sent and its default handler to terminate the process.
hello
world
hello
world
hello
world
terminated
User outlined Signal
Handlers
A method will replace the default signal handler for nearly all signals (but not SIGKILL) by its user’s own handler perform.
A signal handler perform will have any name, however should have return sort void and have one int parameter.
Example: you would possibly opt for the name sigchld_handler for a signal handler for the SIGCHLD signal (termination of a toddler process). Then the declaration would be:
void sigchld_handler(int sig);
When a symbol handler executes, the parameter passed to that is that the range of the signal. A applied scientist will use identical signal handler operate to handle many signals. during this case the handler would wish to ascertain the parameter to examine that signal was sent. On the opposite hand, if a symbol handler function solely handles one signal, it isn’t necessary to hassle examining the parameter since it'll continuously be that signal number.
// CPP program to illustrate
// User-defined Signal Handler
#include<stdio.h>
#include<signal.h>
// Handler for SIGINT, caused by
// Ctrl-C at keyboard
void handle_sigint(int sig)
{
printf("Caught signal %d\n", sig);
}
int main()
{
signal(SIGINT, handle_sigint);
while (1) ;
return 0;
}
^CCaught signal 2 // when user presses ctrl-c
^CCaught signal 2
Sending
signals via kill()
We
can send a signal using kill() to the process
int
kill(pid_t pid, int signal);
pid:
id of destination process
signal:
the type of signal to send
Return
value: 0 if signal was sent successfully
Example :
pid_t
iPid = getpid(); /* Process gets its id.*/
kill(iPid,
SIGINT); /* Process sends itself a SIGINT signal
(commits
suicide?)(because of SIGINT
signal
default handler is terminate the process) */
1. What is the Output of the following program?
#include<stdio.h>
#include<wait.h>
#include<signal.h>
int main()
{
int
stat;
pid_t
pid;
if
((pid = fork()) == 0)
while(1)
;
else
{
kill(pid,
SIGINT);
wait(&stat);
if
(WIFSIGNALED(stat))
psignal(WTERMSIG(stat),
"Child term due to");
}
}
Output:
Child term due to:
Interrupt
2. What is the Output of the following program?
#include<stdio.h>
#include<signal.h>
#include<wait.h>
int val = 10;
void handler(int sig)
{
val += 5;
}
int main()
{
pid_t pid;
signal(SIGCHLD, handler);
if ((pid = fork()) == 0)
{
val -= 3;
exit(0);
}
waitpid(pid, NULL, 0);
printf("val = %d\n", val);
exit(0);
}
#include<signal.h>
#include<wait.h>
int val = 10;
void handler(int sig)
{
val += 5;
}
int main()
{
pid_t pid;
signal(SIGCHLD, handler);
if ((pid = fork()) == 0)
{
val -= 3;
exit(0);
}
waitpid(pid, NULL, 0);
printf("val = %d\n", val);
exit(0);
}
val = 15
3. Consider the following
code. What is the output?
void handler2(int sig)
{
counter += 3;
printf("counter = %d\n", counter);
exit(0);
}
int main()
{
pid_t p;
int status;
signal(SIGUSR1, handler1);
if ((pid = fork()) == 0)
{
signal(SIGUSR1, handler2);
kill(getppid(), SIGUSR1);
while(1) ;
}
if ((p = wait(&status)) > 0)
{
counter += 4;
printf("counter = %d\n", counter);
}
}
Output
counter = 1 //(parent’s handler)
counter = 3 //(child’s handler)
counter = 5 //(parent’s main)
No comments:
Post a Comment