Question: Signals are software interrupts. We can handle signals using the signal library function: #include void (*signal(int sig, void (*func)(int)))(int); This rather complex prototype means that
Signals are software interrupts. We can handle signals using the signal library function:
| #include void (*signal(int sig, void (*func)(int)))(int); |
This rather complex prototype means that signal() is a function that takes two parameters: sig and func. The function to be caught or ignored is specified by argument sig and func specifies the function that will receive the signal; this function must be one that takes a single int argument and is of type void. The signal() function itself returns a function of the same type, which is the previous value of the function set up to handle this signal, or one of the two special values
| SIG_IGN | Ignore the signal. | |
| SIG_DFL | Restore default behavior. |
Learn more about signal using the "man" command:
| $ man signal |
|
//test_signal.cpp #include #include #include using namespace std; void func (int sig) { cout << "Oops! -- I got a signal " << sig << endl; } int main() { (void) signal (SIGINT, func); //catch terminal interrupts for (int i = 0; i < 20; ++i) { cout << "CSUSB CSE 4600 Operating Systems. Homework on signals" << endl; sleep (1); } return 0; } |
Requirement:
Now try the following scripts. Run the program and hit ^C for a few times. What do you see? Why?
Sending Signals
A process can send a signal to itself by calling raise. It can also send a signal to another process (including itself) by calling kill:
| #include int raise (int sig); |
| #include int kill (pid_t pid, int sig); |
Another useful signal function is alarm, which can be used to schedule a SIGALARM signal sometime in the future.
| #include unsigned int alarm (unsigned int seconds); |
The alarm function schedules the delivery of a SIGALARM signal in seconds seconds. Use "man" to study more on raise, kill, alarm.
| //test_alarm.cpp #include #include #include using namespace std; //simulates an alarm clock void alarm_off(int sig) { cout << "Alarm has gone off " << endl; } //tell child process to wait for 5 seconds before sending //a SIGALRM signal to its parent. int main() { int pid; cout << "Alarm testing!" << endl; if ((pid = fork()) == 0) { //child sleep (5); /* Get parent process id, send SIGALARM signal to it. */ kill (getppid(), SIGALRM); return 1; } //parent process arranges to catch SIGALRM with a call //to signal and then waits for the inevitable.
cout << "Waiting for alarm to go off!" << endl; (void) signal (SIGALRM, alarm_off); pause(); //process suspended, waiting for signals to wake up cout << "Done!" << endl; return 1; } |
Requirement:
Try the following "test_alarm.cpp" program. Run "test_alarm.cpp". What do you see? Why?
More Robust Signals Interface
| $ man sigaction |
sigaction is function that provides more robust interface to signals. Use "man" to study this function:
Before calling sigaction(), you should first use sigemptyset() to empty the signal set. (Use '$ man sigemptyset' to find out the details.). Modify your test_signal.cpp program above by using sigaction () to intercept SIGINT; replace the "for" loop with "while (1); you should be able to quit the program by entering "^\". (Need to intercept SIGQUIT.)
can someone help me please using linux?
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
