Article directory
1. Signals at the level of life
Before learning process signals, we might as well know what signals are in reality.
In daily life, eyes, tone of voice, gestures, etc., can all be a signal, all of them可以传递一定信息
. And our common traffic lights, the red light represents the prohibition of passage, the green light represents the permission of passage, and the yellow light represents the transition. These are not what we knew from the beginning, because of the consensus of the public. And all kinds of gestures are also taught by kindergarten teachers, so we can recognize them.
so信号的创建是需要被人们所认知的。
Preliminary knowledge that we can elicit signals through some things in life
进程信号的预备知识
Online shopping is a popular shopping choice today. When the things we shop online are delivered, we will receive the signal of " the delivery has arrived". First, this signal
is the consensus of the public. We can "识别信号
"
When we receive this signal, we may go to pick up the courier immediately, but it is also possible that we are doing something that is inconvenient to leave, so we will not go to pick up the courier immediately. This shows that signal processing and signal reception are not necessarily connected. We can "合适的时候处理信号
"
and, if we don't pick up the courier immediately, we also need to record the signal "the courier has arrived", because we need to deal with it later. We need "记住有一个信号要处理
"
Finally, for the processing of the express, 1.默认动作
(open the express); 2.自定义动作
(if it is a gift for your girlfriend, give it to your girlfriend); 3.忽略
PS: the arrival of the express is irregular,接收快递和我们已经在做的事是异步的
in conclusion:
- Signal creation first needs to be accessible to people
识别
. - It is not necessary to process the signal immediately after receiving the signal,
等到合适的时候再处理
- Because the signal can not be processed immediately, it needs to exist
记录信号的能力
异步
The generation of a signal is true for a process
2. Process signal
We can kill -l
view all process signals through the command
Among them, 1到31是非实时信号
; 34到64是实时信号
.
This blog only learns some non-real-time signals.
The real-time signal, 只需要保存有无产生
, does not need to be processed immediately, and the specific processing can be carried out later.
Operating systems can be divided into 实时系统
and 非实时系统
. Linux和Windows都是非实时系统
, and the real-time system is highly responsive and needs to respond immediately to any naming. For example 车载系统中的刹车
.
There are exactly 32 non-real-time signals, which the operating system uses 位图
to store non-real-time signals. 存储在进程的pcb结构体
, so sending a signal is actually writing the signal into the bitmap of the process pcb, 修改位图的比特位
, will 0->1
.
Bit position: number of the signal
Bit content: whether the signal was received
In Linux, when we accidentally write a program with an infinite loop, we can actually ctrl+c
terminate the program
ctrl+c
by inputting it to the OS through the keyboard, the OS captures it, then sends a signal to the current process, and then terminates the program.
Another point to note is that ctrl+c
only the foreground process can be terminated. If we change the program to run in the background, it cannot be ctrl+c
terminated, but we can use kill+信号
the terminate process
In fact, ctrl+c
the essence is to let the OS send the specified process2号信号SIGINT
singal()
Next, we verify through the function
The signal function can receive a signal, and we specify the action to be performed after receiving the signal.
For example,ctrl+c
the No. 2 signal is sent, and the execution action is终止程序
int signum
: the received signal
sighandler_t handler
: sighandler is one函数指针
, the return value of the function is void, and the parameter is int.
Next, we use a program to prove that ctrl+c
the essence is to send the No. 2 signal
It can be seen that this time we failed to terminate the program by using ctrl+c, and printed out "get signal: 2", and when we sent the signal No. 2, we also executed the handler method. First, we use
,signal函数对2号信号进行捕捉
and让handler作为2号信号的处理动作
.
And the OS will将接收的信号传参给handler
. So we failed to terminate the program by using ctrl+c, but printed out the memory of the handler
. As we mentioned above, there are three types of signal processing:默认动作,自定义动作,忽略
and终止程序就是2号信号的默认动作
thehandler就是自定义动作
We can man 7 signal
view the default action of the signal
Term
to terminate the process
PS: ctrl+\
the signal No. 3, SIGQUIT, is sent, but the signal No. 9, SIGKILL, is an administrator signal. Even if the signal is used to capture and execute a custom action, kill -9 still executes the default action to terminate the process. .
3. Hardware interrupt
We press crtl+c, how does the computer know what data we have entered?
The keyboard is actually 硬件中断
the way through which we inform the operating system 按下了按键
.
注意:硬件中断只是让操作系统知道我们按下了按键,但是具体按了什么,操作系统此时还不知道
So, what is a hardware interrupt?
There is such a hardware in the kernel
中断控制器
. Let's take 8259 as an example. When we press the keyboard, it is actually sent电脉冲
, and then通过中断控制器发送给特定的CPU特定的针脚
. When the pin is on高电频
, it is equivalent to writing写入数据
in the CPU . This is the process similar to that, after the CPU gets an interrupt, it will find the corresponding one in the interrupt vector table . For example, pin No. 9 has a high power frequency, then 9 will be written in the register, and then find the function pointer No. 9 in the interrupt vector table, and call the method of "obtaining the corresponding data from the keyboard". This is a hardware interrupt.寄存器
高电频针脚的编号
发送中断
中断向量表
函数指针数组
函数指针
调用对应的方式
Note: What keys are pressed, and which keys are pressed are two different steps.
The keyboard is pressed, corresponding to
硬件中断
Which of the keyboard is pressed, corresponding to中断向量表中的方法获取键盘输入的数据。
So ctrl+c
the essence of the signal is:
First press the key, the CPU gets it
硬件中断
, and then calls the method, the OS readsctrl+c
the data input by the keyboard, and the OS interprets it as信号
and sends it to the foreground process写入其pcb结构体的信号的位图
.
4. Signal generation
signal 第一种产生方式是通过键盘
, ctrl+c
, ctrl+/
.
第二种
produced bykill指令
第三种产生方式是通过系统调用
The first system call function iskill()
int pid
: Specify to send a signal to a process
int sig
: send a few signals
Next, we can simulate the implementationkill命令
mykill.cc
Simulate the implementation of the kill command
#include<iostream>
#include<cstdlib>
#include<cerrno>
#include<cstring>
#include<unistd.h>
#include<signal.h>
#include<string>
#include<sys/types.h>
using namespace std;
//传参不正确,展示使用手册
void Usage(string proc)
{
cout<<"Usage:"<<endl;
cout<<"\t"<<proc<<" 信号编号 目标进程"<<endl;
}
// ./mykill 9 1234
int main(int argc,char*argv[])
{
//argc:命令行参数个数
if(argc!=3)
{
//第一个参数是 比如: ./进程名
Usage(argv[0]);
exit(1);
}
//信号
int signo=atoi(argv[1]);
//目标进程的pid
int target_id=atoi(argv[2]);
//发送信号
int n=kill(target_id,signo);
if(n!=0)
{
cerr<<errno<<" : "<<strerror(errno)<<endl;
exit(2);
}
return 0;
}
myproc.cc
Infinite loop program, program that needs to be killed
#include<iostream>
#include<unistd.h>
using namespace std;
int main()
{
while(1)
{
cout<<"我是一个进程,我正在执行...,我的pid:"<<getpid()<<endl;
sleep(1);
}
return 0;
}
The result of the operation is as follows:
The second system call function israise()
int sig
: signal number
It can be seen that after calling raise(2), the program ends, and no subsequent content is output.
The third system call function is abort()
调用abort()函数,会给当前进程发送6号信号SIGABRT
but abort() is an interface of the C language, and there are still functions inside 类似exit的操作
, so even if the signal function is used to capture the No. 6 signal and perform a custom action,abort函数还是会使进程终止
第四种
The way the signal is generated is由软件条件产生信号
unsigned int seconds:
seconds秒
sent to the process later14号信号SIGALRM
, but we can trigger it in advance by sending signal 14alarm
. And when we call alarm() again, its return value is上一次alarm还剩余的时间
.
But if we trigger the alarm in advance, however没有重新设置
, then之后还会再收到一次alarm
. alarm(0) means to cancel the alarm clock.
For example, we set an alarm(30), but if I send the signal No. 14 to the process at 20 seconds, and then I call alarm(15), then another 15 seconds will be set Alarm clock, but the return value of this alarm clock is the remaining time of the last alarm clock, which is 10 seconds.
PS: alarm is a system interface. There is a structure for maintaining the alarm in the OS, and it will regularly check whether there is an alarm clock timeout.
第五种
The way the signal is generated is硬件异常
When we write C/C++ code, sometimes there may be 除0
and their error reports are as follows. 野指针
Our previous understanding at the language level is that the program crashes. But at the operating system level, it is actually the OS that sends a signal to the process to terminate the process.
除0引发的硬件异常
There are actually many registers in the CPU, and calculations happen in the registers. And there is a register called
状态寄存器
, when this time计算溢出
, the status register will be置为1
,反之为0
.
And once状态寄存器为1
it happens硬件异常
, the operating system will be notified of the exception. The CPU will also store it当前调度的进程的pcb结构体的地址
. After the operating system learns of the exception, it will give the process the发送信号
The essence of dividing by 0 is triggered 硬件异常
, and the operating system sends the process8号信号
野指针引发的硬件异常
If we dereference a null pointer, modify its internal value.
By default, the null pointer is the 0 address of the virtual address, and
the value inside the pointer is mapped to the physical address through the page table. The first step is to modify the value inside the pointer.进行虚拟地址到物理地址的转换
The page table actually existsMMU硬件
— the PS内存管理单元
for management
: MMU hardware is one of the hardware of the CPU
When one of the following situations occurs, the MMU will report an error,触发硬件异常
- Virtual address
没有映射
, MMU hardware error有映射,但是没有修改的权限
, MMU hardware errorThe MMU hardware reports an error and triggers a hardware exception. The OS sends a signal to terminate the process according to the pcb address of the current process recorded in the CPU.
The nature of the wild pointer is also triggered 硬件异常
, and the operating system sends the process11号信号
五. Term&Core
As we said before, Term means to terminate the process, but the division of 0 just now, the number 8 of the wild pointer, and the signal number 13 are Core, but it seems to terminate the process directly, so what is the difference between the two?
First of all, when a process is abnormal, it can perform a core dump of the core code part, and dump all the relevant data of the process in the memory to the disk. And in the directory of the executable program, a core dump file of core.pid is formed.
We can check the limit of the current process through the ulimit -a command.
Why didn’t we see the core dump file before? Because the cloud server disables the function of forming a core dump file by default, and the size of the core dump file that can be formed Set to 0.
We can use to ulimit -c 大小
set the size of the core dump file that can be formed.
At this time, we can find the difference between Term and Core.
We found that the Action display is the signal of the Core. After the process is terminated, it will be displayed (core dumped)
and formed in the current directory.core文件
Therefore, when
Term的终止就是终止
there is no redundant action
, Core will terminate先进行核心转储,再终止进程
1. The meaning of core dump
We opened the core file and found that it was actually one 二进制文件
. Not for us. So
what's the point of the core dump?
In fact, the function of the signal and the exit code is the same. They are both after the end of the process. When 反馈给程序员的信息
the program ends abnormally, we can know whether it is a normal end or an abnormal termination; what is the reason for the abnormal termination?
The core file is actually 调试
a file for programmers to use later.
We need to use it Debug方式
to form an executable program and use it gdb调试
to understand the meaning of the core file. (gcc / g++ is the release version by default, and the -g option is added at the end to form the Debug version)
通过core文件,我们在gdb的调试中,可以直接定位到产生异常的位置。
This debugging is called事后调试
2. Why does the cloud server disable core dump
A large program, when a problem occurs, cannot be solved immediately, the program may crash, but there may be a detection program to restart it, and if the core dump is turned on, a crash will form a core file; if this program If it crashes in the middle of the night, it will 一直重启,崩溃
be repeated, and the process of each restart is different. As mentioned above, the same program has a different pid after becoming a process Core终止就会重新形成一个core文件
.
This will happen 造成很多浪费
, so the cloud server generally turns off the core dump function.
ulimit -c 0
is to turn off the core dump
3. core dump flag
When the process is waiting, the status bitmap structure used by the parent process to obtain the exit information of the child process.
When the process is terminated normally, the 8~15 bits of the bitmap are
when the exit code is killed by the signal, 0~6 is the termination signal, and the 8th bit is the termination signal. bit is the core dump flag.
If the core dump function of the process is enabled, the core dump of the process is 1, otherwise it is 0.
6. Summary
- All signal generation must be executed by the OS in the end, because
OS是软硬件的管理者
it is also进程的管理者
- The signal can be processed
不立刻处理
, and the process can合适的时候
process the signal again- If not processed immediately, the signal needs to be logged
pcb结构体
into- When a process does not receive a signal, it knows how to handle a certain signal, because it has been provided to each process during coding
- Any kind of signal generation, whether it is through the keyboard, or commands, system calls... the essence is
操作系统往进程的pcb结构体中写入信号
conclusion
This concludes the content of this article, thank you for reading!
If there is anything to add or correct, please add and correct in the comment area. If you think this article is helpful to you, you might as well like it to support the blogger, please, this is really important to me.