A signal is a limited form of inter-process communication used in Unix, Unix-like, and other POSIX-compliant operating systems. Essentially it is an asynchronous notification sent to a process in order to notify it of an event that occurred. When a signal is sent to a process, the operating system interrupts the process's normal flow of execution. Execution can be interrupted during any non-atomic instruction. If the process has previously registered a signal handler, that routine is executed. Otherwise the default signal handler is executed.
Definition:
Signals are software interrupts, providing a means to handle asynchronous events.
Signals are software interrupts, providing a means to handle asynchronous events.
Signal Categories
Signals can be classified into 5 categories.
• Process control.
SIGHUP: hang-up, usually sent by the parent process to child processes when terminating.
SIGKILL: kill (cannot be caught of ignored)
SIGTERM: Software termination signal from kill
SIGABRT: Process abort signal
SIGHUP: hang-up, usually sent by the parent process to child processes when terminating.
SIGKILL: kill (cannot be caught of ignored)
SIGTERM: Software termination signal from kill
SIGABRT: Process abort signal
• Job control.
SIGCHLD: Child process has stopped or terminated.
SIGSTOP: Stop signal (cannot be caught or ignored)
SIGTSTP: Interactive stop signal.
SIGCONT: Continue if stopped.
SIGTTIN: Read from control terminal attempted by a member of a background process group.
SIGTTOU Write to control terminal attempted by a member of a background process group.
• Environment change.
SIGWINCH: indicates window size change.
SIGINT: Interrupt, generated by Ctrl-C
SIGQUIT: quit, generated by Ctrl-\ Ctrl-break
SIGILL: Illegal instruction (not reset when caught)
SIGTRAP: trace trap (not reset when caught)
SIGIOT: IOT instruction
SIGEMT: EMT instruction
SIGFPE: Floating point exception
SIGBUS: bus error
SIGPWR: power state indication
SIGIO asynchronous I/O
SIGURG urgent condition on IO channel
• Software condition.
SIGSYS: bad argument to system call
SIGPIPE: write on a pipe with no one to read it
SIGALRM: alarm clock
SIGSEGV: Segmentation violation
SIGVTALRM: virtual timer alarm
SIGPROF: profiling timer alarm
Signal Properties
Persistence
Process-persistent.
Name space
PID and signal numbers.
Permission
Processes of the same group can send each other signals. Superuser (root) can send signal to all processes.
Latency
A few hundred micro-seconds on general-purpose Unix (e.g. HP-UX, Linux) or a few micro-seconds on a RTOS (3.3 us on Pentium-166, QNX).
Limitations
A limited number of signals (normally 32). Two of them can be defined by users.
ANSI C signal()
ANSI C defines the simplest signal handling function.
#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int);
signal() instantiates a signal handler for the given signal and returns the signal handler
instantiated earlier.
Example
static void signalHandler(int); /* signal handler function */
signal(SIGHUP, &signalHandler); /* instantiate signal handler */
Macros SIG_ERR, SIG_DFL and SIG_IGN.
signal(sig, SIG_DFL); /* reset to default signal handler. */
signal(sig, SIG_IGN); /* ignore the signal. */
This is normally sufficient for basic signal handling.
int receivedSignal_g = 0;
int receivedSignalNo_g = 0;
static void signalHandler(int);
int main(int argc, char* argv[])
{
signal(SIGHUP, &signalHandler);
while (receivedSignalNo_g != SIGTERM) {
if (receivedSignal_g) {
printf("Received signal: %d\n", receivedSignalNo_g);
receivedSignal_g = 0; receivedSignalNo_g = 0;
}
sleep(60);
}
}
static void signalHandler(int signalNumber) {
signal(signalNumber, signalHandler); /* re-establish the signal handler. */
receivedSignal_g = 1;
receivedSignalNo_g = signalNumber;
}
Related System Calls
//Sending a signal
#include <signal.h>
int raise(int sig); /* send a signal to itself */
int kill(pid_t pid, int sig); /* send a signal to process PID */
#include <signal.h>
int raise(int sig); /* send a signal to itself */
int kill(pid_t pid, int sig); /* send a signal to process PID */
kill() can be used to determine whether a process has terminated.
kill(aPid, 0);
kill(aPid, 0);
If kill() returns -1 and errno is set to ESRCH, the aPid process is no longer around.
System call abort() is implemented with raise(SIGABRT), sending SIGABRT to itself.
//Waiting for a signal
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
int pause(void);
//Waiting for a signal
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
int pause(void);
System call sleep() is implemented with alarm() and pause().
System Commands
kill() - sends a signal to a process, or by default, terminates a process.
kill [-s signame] pid ...
kill [-s signum] pid ...
kill -l // list all signal values.
kill [-s signum] pid ...
kill -l // list all signal values.
Obsolescent Versions:
kill -signame pid ...
kill -signum pid ...
Sample Signal C code
/*
* signal.c, communication between
* signal.c, communication between
* child and parent processes using kill() and signal().
* fork() creates the child process from the parent. The pid can be checked to decide
* whether it is the child (== 0) * or the parent (pid = child process id).
* The parent can then send messages to child using the pid and kill().
* The child picks up these signals with signal() and calls appropriate functions.
* An example of communicating process using signals is signal.c:
* signal.c --- Example of how 2 processes can talk
* to each other using kill() and signal()
* We will fork() 2 process and let the parent send a few
* signals to it`s child
* gcc signal.c -o signal
*/
#include <stdio.h>
#include <signal.h>
void sighup(); /* routines child will call upon sigtrap */
void sigint();
void sigquit();
void main() {
int pid;
/*
* get child process
*/
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
}
if (pid == 0) { /* child */
signal(SIGHUP,sighup); /* set function calls */
signal(SIGINT,sigint);
signal(SIGQUIT, sigquit);
for(;;); /* loop for ever */
} else { /* parent */
/*
* pid hold id of child
*/
printf("\nPARENT: sending SIGHUP\n\n");
kill(pid,SIGHUP);
sleep(3); /* pause for 3 secs */
printf("\nPARENT: sending SIGINT\n\n");
kill(pid,SIGINT);
sleep(3); /* pause for 3 secs */
printf("\nPARENT: sending SIGQUIT\n\n");
kill(pid,SIGQUIT);
sleep(3);
}
}
void sighup(){
* fork() creates the child process from the parent. The pid can be checked to decide
* whether it is the child (== 0) * or the parent (pid = child process id).
* The parent can then send messages to child using the pid and kill().
* The child picks up these signals with signal() and calls appropriate functions.
* An example of communicating process using signals is signal.c:
* signal.c --- Example of how 2 processes can talk
* to each other using kill() and signal()
* We will fork() 2 process and let the parent send a few
* signals to it`s child
* gcc signal.c -o signal
*/
#include <stdio.h>
#include <signal.h>
void sighup(); /* routines child will call upon sigtrap */
void sigint();
void sigquit();
void main() {
int pid;
/*
* get child process
*/
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
}
if (pid == 0) { /* child */
signal(SIGHUP,sighup); /* set function calls */
signal(SIGINT,sigint);
signal(SIGQUIT, sigquit);
for(;;); /* loop for ever */
} else { /* parent */
/*
* pid hold id of child
*/
printf("\nPARENT: sending SIGHUP\n\n");
kill(pid,SIGHUP);
sleep(3); /* pause for 3 secs */
printf("\nPARENT: sending SIGINT\n\n");
kill(pid,SIGINT);
sleep(3); /* pause for 3 secs */
printf("\nPARENT: sending SIGQUIT\n\n");
kill(pid,SIGQUIT);
sleep(3);
}
}
void sighup(){
signal(SIGHUP,sighup); /* reset signal */
printf("CHILD: I have received a SIGHUP\n");
}
void sigint() {
signal(SIGINT,sigint); /* reset signal */
printf("CHILD: I have received a SIGINT\n");
}
void sigquit() {
printf("My DADDY has Killed me!!!\n");
exit(0);
}
printf("CHILD: I have received a SIGHUP\n");
}
void sigint() {
signal(SIGINT,sigint); /* reset signal */
printf("CHILD: I have received a SIGINT\n");
}
void sigquit() {
printf("My DADDY has Killed me!!!\n");
exit(0);
}
No comments:
Post a Comment