16. Inter-process communications: signals
Already known: pipes
- Byte data
- Synchronous: faster side waits
Signals
Already known: terminal keyboard input (C, Z, ^\)
Signal is:
- Asynchronous
- One-byte
- Delivered by OS
- Can be caught by OS or the process itself
Example simple never-end program:
kill utility — send a signal to a process
kill -l
- ⇒ (slightly) platform-depended
kill -SIGNAL
- example: suspend (STOP) / continue (CONT)
kill never-ending program with just kill, kill -HUP, 9, SEGV :), STOP and CONT
BTW:
interactive process: ⩽1 at each terminal
- can input and output to the terminal
background process (runs from shell with '&'): any number
- can only output to the terminal
It's just a convention, both types runs by fork()/exec()
So:
^Z to stop, fg to continue, bg to continue in background (complex)
When background process inputs from tty, in immediately STOPped, we can fg it
Sending and catching signals
Base article: GeeksforGeeks
Send a signal: kill
see perror
- try to kill foreign or non-existent process
Handler (signal):
needs to be registered
- not all signals can be handled (e. g. 9 and STOP/CONT)
- permission restrictions (by process UID)
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <signal.h>
4
5 void handler(int sig) {
6 printf("Caught %d\n", sig);
7 }
8
9 int main(int argc, char *argv[]) {
10 signal(SIGINT, handler);
11 signal(SIGSEGV, handler);
12 int i;
13 for(i=0;; i++) {
14 sleep(1);
15 printf("%d\n", i);
16 }
17 return 0;
18 }
Looking after child process:
1 #include <stdio.h>
2 #include <wait.h>
3 #include <signal.h>
4 #include <unistd.h>
5
6 int main(int argc, char *argv[]) {
7 int stat;
8 pid_t pid;
9 if ((pid = fork()) == 0)
10 while(1) ;
11 else
12 {
13 printf("Forking a child: %d\n", pid);
14 wait(&stat);
15 printf("And finally…\n");
16 if (WIFSIGNALED(stat))
17 psignal(WTERMSIG(stat), "Terminated:");
18 printf("Exit status: %d\n", stat);
19 }
20 return 0;
21 }
H/W
TODO