Lets create the signal handler. Pretty straight forward... If we get the SIGUSR1 signal, print out a message to stdout
// signal handler function void sig_handler (int signo) { if (signo == SIGUSR1) cout << "got SIGUSR1" << endl; }
Next, we need to tell our application to listen for the signal. We do that by calling signal(). If we try to register our listener and something fails or a that signal can't be listened to, we will see an error message printed out to stdout. Note, not all message can be trapped and acted upon. For example, SIGKILL can't be caught. If you were to try and register a listener for it (I encourage you to do so), you will see it will fail.
if (signal(SIGUSR1, sig_handler) == SIG_ERR) cout << "Unable to catch SIGUSR1" << endl;
Now, if we put this all together and run our program, we can try to send the SIGUSR1 signal and see if we trap it in our application. Here is a complete example (signal-receiver.cpp).
#include <iostream> #include <signal.h> #include <stdio.h> using namespace std; // signal handler function void sig_handler (int signo) { if (signo == SIGUSR1) cout << "got SIGUSR1" << endl; } int main() { if (signal(SIGUSR1, sig_handler) == SIG_ERR) cout << "Unable to catch SIGUSR1" << endl; // simulate a long process - calling sleep() so CPU doesn't go to 100% while (1) sleep(1); return 0; }
To compile, nothing special.
g++ -Wall signal-receiver.cpp -o signal-receiver
Run and send the SIGUSR1 signal. Notice the program does not terminate upon receiving the signal. You can send it over and over and it will not terminate. Try commenting out the adding of the listener in the program above, re-compile, and run. When you send the SIGUSR1 signal, it will terminate your application.
$ ./signal-receiver got SIGUSR1 got SIGUSR1 got SIGUSR1
To send the signal from the command line
$ kill -USR1 <PID>
Lastly, if you are curious if you can send a signal from another c++ program, the answer is yes! Here is a simple example.
#include <iostream> #include <signal.h> using namespace std; int main (int argc, char* argv[]) { if (argc != 2) { cout << "Usage: " << argv[0] << " <PID>" << endl; return 1; } int ret; ret = kill(atof(argv[1]), SIGUSR1); if (!ret) cout << "Successfully sent signal"; else cout << "Error sending signal"; cout << endl; return 0; }
No comments :
Post a Comment