16.1 (Conspect) Inter-process communications: signals

The topic is very big - we'll only discuss the signals.

ctrl+c

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:

   1 #include <stdio.h>
   2 #include <unistd.h>
   3 
   4 int main(int argc, char *argv[]) {
   5         int i;
   6         for(i=0;; i++) {
   7                 sleep(1);
   8                 printf("%d\n", i);
   9         }
  10         return 0;
  11 }

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)

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

   1 #include <stdio.h>
   2 #include <sys/types.h>
   3 #include <signal.h>
   4 #include <stdlib.h>
   5 
   6 int main(int argc, char *argv[]) {
   7         if(kill(atoi(argv[1]), atoi(argv[2])))
   8                 perror("Can't kill");
   9         return 0;
  10 }

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 }

HSE/ProgrammingOS/16_IPC/Conspect_en (последним исправлял пользователь NataliaKrauze 2020-03-23 20:16:19)