/* File: /home/faculty/liux/public_html/courses/cop4610/examples/sig_handle.cc Purpose: Demonstrate how to use signal for Cop4610, Author: Xiuwen Liu, based on an example in Advanced Programming in the UNIX Environment, by W. Richard Stevens, Addison-Wesley, 1992 On the web: http://www.cs.fsu.edu/~liux/courses/cop4610/examples/sig_handle.cc Compiling command: g++ -o sig_handle sig_handle.cc Exercise: ./sig_handle & Then try to send some signals to the running process using kill, for example (suppose the process id is 22502): kill -INT 22502 kill -USR1 22502 kill -QUIT 22502 kill -KILL 22502 (or kill -9 22502) */ /* Questions: 1. What is a signal? What is an asynchronous event? What is an interrupt? 2. Who is handling the signal? Who is running the sig_handler procedure when the running process receives a signal SIGINT? 3. Suppose the processing id of the process is 22502. If we type kill -2 22502 kill -2 22502 Why is the response of the process different for the two cases? 4. Why do people using "kill -9" to terminate a wild-running process? */ #include #include #include #include void sig_handler(int); /* A signal handler example */ int i, j, k; int interrupted; int main(void) { int anarray[100]; int interrupted=0; i = 0; j = 0; k = 0; /* Use signal to change the interpret handler for some signals */ if (signal(SIGUSR1, sig_handler) == SIG_ERR) cerr << getpid() << " Could not catch signal SIGUSR1." << endl; if (signal(SIGUSR2, sig_handler) == SIG_ERR) cerr << getpid() << " Could not catch signal SIGUSR2." << endl; if (signal(SIGINT, sig_handler) == SIG_ERR) cerr << getpid() << " Could not catch signal SIGUSR2." << endl; /* if (signal(SIGSEGV, sig_handler) == SIG_ERR) cerr << getpid() << " Could not catch signal SIGSEGV." << endl; */ for (;;) { i = 2000; k = 0; for (j=0; j < i; j++) { k += j; } i = 1980; k = 0; for (j=0; j < i; j++) { k += 2*j; } i = 2020; k = 0; for (j=0; j < i; j++) { k += j; } anarray[0] = 0; i =0; /* do { i++; anarray[i] = anarray[i-1]+2; if (i==0) break; if (interrupted !=0) break; } while(i >0 && interrupted ==0); */ } } void sig_handler(int signo) /* signo: Signal number defined in */ { /* Reset to the interpret handler */ signal(signo, sig_handler); switch(signo) { case SIGUSR1: cout << getpid() << ": Receieved signal SIGUSR1 = " << signo <<"." << endl; printf("Values of variables: i = %d j = %d k = %d.\n", i, j, k); break; case SIGUSR2: cout << getpid() << ": Receieved signal SIGUSR2 = " << signo <<"." << endl; printf("Values of variables: i = %d j = %d k = %d.\n", i, j, k); break; case SIGINT: cout << getpid() << ": Receieved signal SIGINT = " << signo <<"." << endl; printf("Values of variables: i = %d j = %d k = %d.\n", i, j, k); break; case SIGSEGV: interrupted = 1; cout << getpid() << ": Receieved signal SIGSEGV = " << signo <<"." << endl; printf("Values of variables: i = %d j = %d k = %d.\n", i, j, k); i = 0; exit(0); break; default: cout << getpid() << ": Received signal " << signo << " with unknown type." << endl; } return; }