signal |
A s ignal is a software interrupt. UNIX supports about 30 signals, each with a unique integer code. The signals are numbered sequentially, starting with the number one. You can program the current process to react to a particular signal in one of these ways.
In addition, you can program the current process to block certain signals. Blocked signals are queued and only delivered if they are unblocked. Some signals are so common they have a function named after them. These function names are listed in the following table.
| Signal | Function |
|---|---|
The examples in this section illustrate the various uses of signals.
The following example shows the
result of a current process receiving a SIGTERM
signal. The current process reacts in the default manner by displaying the
message "Terminated" and terminating without dumping core.
Once a process object is
associated with a running process, you can suspend, resume, or terminate it
using suspend() , resume()
, or terminate() . These functions operate by
sending the process a signal. The following example demonstrates all of these
functions.
#include <iostream>
#include <ospace/unix.h>
int
child_function()
{
while ( true ) // Loop forever.
{
cout << "Child loop" << endl;
os_this_process::sleep( 1 );
}
return 0; // Will never execute.
}
int
main()
{
os_unix_toolkit initialize;
os_process child( child_function ); // Spawn child.
os_this_process::sleep( 4 );
cout << "child.suspend()" << endl;
child.suspend();
cout << "Parent sleeps for 4 seconds" << endl;
os_this_process::sleep (4);
cout << "child.resume()" << endl;
child.resume ();
os_this_process::sleep (4);
cout << "child.terminate()" << endl;
child.terminate ();
cout << "Parent finished" << endl;
return 0;
}
Child loop
Child loop
Child loop
Child loop
Child loop
child.suspend()
Parent sleeps for 4 seconds
child.resume()
Child loop
Child loop
Child loop
Child loop
child.terminate()
Child loop
Parent finished
The following example uses set_alarm()
to send a SIGALRM
signal to the current process after four seconds. The process reacts in the
default manner by displaying the message " Alarm
Clock" and terminating.
#include <iostream>
#include <ospace/unix.h>
int
main()
{
os_unix_toolkit initialize;
cout << "Set the alarm for 4 seconds." << endl;
os_this_process::set_alarm( 4 );
cout << "Pause for a signal..." << endl;
os_this_process::pause(); // Wait for a signal.
cout << "Program terminated OK" << endl; // Never executed.
return 0;
}
Set the alarm for 4 seconds.
Pause for a signal...
Alarm Clock
In the next example, the current
process is set to block SIGUSR1
signals and send a SIGUSR1 to itself. The pending_signals()
function shows that SIGUSR1
is queued. When SIGUSR1 is unblocked, it is
delivered to the current process, which terminates and displays "User
Signal 1."
#include <iostream>
#include <ospace/unix.h>
int
main()
{
os_unix_toolkit initialize;
os_this_process::block( SIGUSR1 );
vector< ossig_t > blocked = os_this_process::blocked_signals();
cout << "Blocked signals = ";
for ( int i = 0; i < blocked.size(); i++ )
cout << os_signal( blocked[ i ] ) << " ";
cout << endl;
os_this_process::signal( SIGUSR1 );
vector< ossig_t > pending = os_this_process::pending_signals();
cout << "Pending signals = ";
for ( i = 0; i < pending.size(); i++ )
cout << os_signal( pending[ i ] ) << " ";
cout << endl;
os_this_process::unblock( SIGUSR1 );
cout << "Terminating OK" << endl; // Never executed.
return 0;
}
Blocked signals = os_signal( 16, User Signal 1 )
Pending signals = os_signal( 16, User Signal 1 )
User Signal 1
To ignore and discard a signal,
use ignore() . To
restore the default action, use restore_default()
. The following example shows how programs can use
these functions to protect their critical regions from the interrupt signal, SIGINT
(Control-C).
T he SIGKILL
and SIGSTOP signals can never be ignored or
discarded.
#include <iostream>
#include <ospace/unix.h>
int
main()
{
os_unix_toolkit initialize;
os_this_process::ignore( SIGINT );
cout << "Try and kill me with a Control-C (SIGINT)" << endl;
os_this_process::sleep( 5 );
os_this_process::restore_default( SIGINT );
cout << "Try again" << endl;
os_this_process::sleep( 5 );
cout << "Terminating OK" << endl; // Never executed.
return 0;
}
Try and kill me with a Control-C (SIGINT)
^C^C^C (Doesn't work)
Try again
^C (Terminates the program)
Many of the signal-related
functions can take either a single signal or a vector of signal codes as a
parameter. In the following example, a set of signals is blocked, sent, and
unblocked. When the first blocked signal, SIGALRM
, is delivered, the current process terminates
with the message "Alarm Clock."
To denote an empty set of
signals, use the predefined object os_signal::empty_set
.
#include <iostream>
#include <ospace/unix.h>
int
main()
{
os_unix_toolkit initialize;
vector< os_sig_t > signals;
signals.push_back( SIGALRM );
signals.push_back( SIGTERM );
cout << "Blocking ";
os_this_process::block( signals );
os_this_process::signal( SIGALRM );
os_this_process::signal( SIGTERM );
cout << "OK so far" << endl;
os_this_process::unblock( signals );
cout << "Terminating OK" << endl; // Never executed.
return 0;
}
Blocking OK so far
Alarm Clock
Copyright©1994-2026 Recursion
Software LLC
All Rights Reserved - For use by licensed users only.