16.1 (Conspect) Inter-process communications: signals
The topic is very big - we'll only discuss the signals.
- The signals are actually familiar to us - we deal with them all the time when we command our processes from the keyboard. For example, we take some process - we write 100 in the sleep terminal - and it hangs for 100 seconds. We want to kill this process - that is, we press key combination
ctrl+c
- ctrl+c - is actually a keyboard combination that handles the terminal, instead of just sending a bow to the process with code 3(ctrl+c has code 3), it sends a signal. From a shell perspective, this is an interrupt, but not really.
Besides signals, we know another way of interprocess communication - data transmission through channels.
Signals
A signal is such a message, we deliver it to your program asynchronously (at the moment when it least expects it can receive a signal and start processing it), the size of this message is 1 byte (the signal consists only of its own type and nothing else), the delivery of this message is the operating system (that is, it is a system call)
( commands 'fg', 'bg').
sleep 100
She works there somehow, we see where he is.
pidof sleep
Gives out a certain number You can nail it, you can stop it. Runs a kill program that sends some kind of signal to the process. The surprise is that different hardware architectures have different lists of kill signals.
kill // the number that gave us previously in the terminal
writing a program that we're going to kill:
THIS PROGRAM IS ETERNAL, SLEEPS ONE NUMBER, SLEEPS ONE SECOND, THEN... WRITE ANOTHER NUMBER AND SO ON. We look at her indicator and kill her like we did above sleep 100.
suspend (STOP) / continue (CONT)
-CONT works like nothing ever happened after we killed him. The scariest signal is SIGKILL - everyone dies after it. (-9)
- When we work in a command line - apart from an interactive process that runs from the command line - we can only run one, we can run any number of background processes.
There is a killall utility - which kills the process by name.
Translating the process into the background is not a very simple command because the difference between the front process and the back process has the right to write and read from the terminal, and the back process has the right only to write.
Send a signal: kill
- It returns the status of the error - if it suddenly turns out that it is not 0 - we say perror - it outputs the line + the name of the error that occurred.
Try to kill foreign or non-existent process: When we do this operation is not allowed - in reality the transmission of a signal to some process is strictly limited by the master (root).
Write a signal handler - A function that will suddenly be called asynchronously when our process receives a signal. And if you have registered this handler, instead of killing this process, OS will pass the processed signal to our handler and everything will be fine:
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 }
We made a program that can process two signals (SIGINT and SIGSEGV) - and then print meaningless messages.
Our process generates a child process - shell - a program to generate processes and work with them - in the trailer this is often said when we write a system program, we need to generate a process using fork().
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 }