Linux signal learning notes

Posted by jokerfool on Tue, 30 Nov 2021 17:14:29 +0100

Linux signal learning notes (1)

Program running

  there are several ways to abort this program when the following code is running.

#include<unistd.h>
#include<stdio.h>
using namespace std;
int main()
{
    for(int i=1;i<=100;i++)
    {
        printf("time of programe running:%ds\n",i);
        sleep(1);
    }
}

1.   the method of using "ctrl+c" combination key in the terminal running the program can be terminated:

~$ ./demo_1
time of programe running:1s
time of programe running:2s
time of programe running:3s
^C

2.   when the program is running, use the ps -ef|grep process keyword in the terminal (open another one) to get the process number, and then use the "kill process number" to terminate:

~$ ps -ef|grep demo_1
mrlop     13554  13146  0 18:47 pts/0    00:00:00 ./demo_1
mrlop     13602  13524  0 18:47 pts/1    00:00:00 grep --color=auto demo_1
~$ kill 13554

   at this time, there will be the following contents in the terminal running the program:

~$ ./demo_1
time of programe running:1s
time of programe running:2s
time of programe running:3s
 Terminated

3.     when the program is running, use the "kill process keyword" to terminate:

~$ killall demo_1

   at this time, there will be the following contents in the terminal running the program:

~$ ./demo_1
time of programe running:1s
time of programe running:2s
time of programe running:3s
 Terminated

Linux signal

   in the above contents, signals are sent to the "demo_1" program to terminate it, in which "ctrl+c" is to send SIGINT signals, kill and kill are to send SIGTERM signals, and other signals and functions can query the Linux signal table, and the Linux signal list can be obtained by using the "kill -l" instruction.

~$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

  therefore, SIGINT code is 2 and SIGTERM code is 15. Kill can also use "kill - signal code process number" or "kill - signal name process number" to send other signals to the corresponding process. If the intermediate parameters are not added, SIGTERM signal is sent.

signal function

  use the function declared in the signal.h Library:

__sighandler_t signal (int __sig, __sighandler_t __handler)

   the first parameter in the signal function is the signal name or signal code, and the second parameter is the name of the processing function running when the signal is received. The second parameter of the signal function can also fill in "signal" to ignore the signal, and "SIG_DFL" replies that the processing method of the signal is the default.
  the modification procedure is as follows:

#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
void handle(int sig)
{
    printf("receive signal:%d, program exit\n",sig);
    exit(0);
}
int main()
{
    signal(15,handle);
    for(int i=1;i<=100;i++)
    {
        printf("time of programe running:%ds\n",i);
        sleep(1);
    }
}

    when running, the process ends with "kill demo_2". The process will receive 15 signals, and the 15 signals will be processed by the handle function. The following results were obtained:

~$ ./demo_2
time of programe running:1s
time of programe running:2s
time of programe running:3s
receive signal:15, program exit

    however, it is worth noting that even if "signal(9,handle)" is added to the code, the program will still be directly killed when "kill -9 demo_2" is used, because SIGKILL(9) and SIGSTOP(19) cannot be shielded.

~$ ./demo_2
time of programe running:1s
time of programe running:2s
 Killed

kill function

kill function is provided in   c language for sending signals:

int kill (__pid_t __pid, int __sig)

   the first parameter is the destination process number of the signal to be transmitted, and the second parameter is the signal code of the signal to be transmitted. In the following code, the parent process sends 15 signals to the child process.

#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
void handle(int sig)
{
    printf("receive signal:%d, my pid=%d, my parent pid=%d, program exit.\n",sig,getpid(),getppid());
    exit(0);
}
int main()
{
    int pid;
    pid=fork();
    if(pid>0)
    {
        printf("parent pid:%d.\n",getpid());
        sleep(1);
        kill(pid,15);
        sleep(2);
    }
    else
    {
        printf("child pid:%d.\n",getpid());
        signal(15,handle);
        sleep(2);
    }  
}

    in order to avoid the wrong timing of signal transmission and the inconsistent parent process number obtained by the child process getppid() due to the premature end of the parent process, the sleep() function is used. The following operation results can be obtained:

~$ ./demo_3
parent pid:15694.
child pid:15695.
receive signal:15, my pid=15695, my parent pid=15694, program exit.

Topics: C++ Linux