嗨,大家好,我是出生在达纳苏斯的一名德鲁伊,我是要立志成为海贼王,啊不,是立志成为科学家的德鲁伊。最近,我发现我们所处的世界是一个虚拟的世界,并由此开始,我展开了对我们这个世界本源的探索。那么就由我来带领大家拨开迷雾,深入探究我们世界的根本。
前两期我们介绍了src/server/apps/authserver目录下的Main.cpp文件中的main函数的第一行代码,那么我们继续向下进行。
signal顾名思义,是接收信号的代码。接收到SIGABRT信号后,会触发Acore::AbortHandler函数。AbortHandler函数的定义在src/common/Debugging/Errors.cpp中。那么今天的知识点来了,信号处理。
信号处理
C++中的信号处理是指操作系统通过信号中断来向进程发送中断请求的过程。这些中断可以导致程序被意外终止。在C++中,您可以使用头文件中定义的信号来捕获这些中断,并根据信号采取适当的行动。以下是一些常见的信号及其描述:
- SIGABRT:程序异常终止,比如调用abort函数。
- SIGFPE:错误的算术操作,比如除以零或导致溢出的操作。
- SIGILL:检测到非法指令。
- SIGINT:接收到交互式中断信号。
- SIGSEGV:对存储空间的无效访问。
- SIGTERM:发送给程序的终止请求。
在C++中,您可以使用signal()函数来捕获这些信号。signal()函数的语法如下:
void (*signal(int sig, void (*func)(int)))(int);
这个函数接受两个参数:第一个参数是表示信号编号的整数,第二个参数是指向信号处理函数的指针。您可以使用signal()函数来注册信号并将其与信号处理程序关联起来。以下是一个简单的示例:
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler(int signum)
{
cout <nterrupt signal (" << signum << ") received.\n";
exit(signum);
}
int main()
{
signal(SIGINT, signalHandler);
while(1) {
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}
在这个示例中,我们使用signal()函数来捕获SIGINT信号,并将其与名为signalHandler的信号处理函数关联起来。当程序运行时,如果按下Ctrl+C,程序将捕获该信号并执行相应的处理程序。
除了使用signal()函数外,您还可以使用raise()函数来生成信号。raise()函数接受一个整数信号编号作为参数,用于生成相应的信号。以下是一个使用raise()函数的示例:
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler(int signum)
{
cout << "Interrupt signal (" << signum << ") received.\n";
exit(signum);
}
int main()
{
signal(SIGINT, signalHandler);
int i = 0;
while(++i) {
cout << "Going to sleep...." << endl;
if( i == 3 ) {
raise(SIGINT);
}
sleep(1);
}
return 0;
}
在这个示例中,我们在循环中使用raise()函数生成SIGINT信号。当程序执行到i等于3时,会生成该信号并执行相应的处理程序。
总之,C++中的信号处理机制可以帮助您捕获和处理来自操作系统的中断请求,使您的程序能够更加健壮和可靠。
类比学习
想象一下,你是一个网约车司机,此时你正在载人行驶中,你的手机会时不时的提示你,有新的订单可以抢,当你觉得订单可以接时,你就会立即抢单。这个过程,像极了在运行的程序,突然被信号打断,进而优先处理信号逻辑。
代码解析
AbortHandler从代码中可以发现,其实它的逻辑很简单,就是记录并输出进程接收到了什么信号,然后调用Crash将进程直接退出。
好了,今天就到这里吧,我要去呵护我的世界之树了,拜拜。