我翻阅了我近来服务器项目的框架?见到了讯号处理代码块,主要有两个功能点:
1.配置文件
2.让服务程序完美中止(在中止前触发清除资源的操作)。
讯号的本质
操作系统给进程发送讯号,本质上是给进程的PCB中写入数据,更改相应的PCB数组,进程在合适的时间去处理所接收到的讯号。下边我们模拟下这样的一个场景。
(1)用户输入一个命令信号与信息处理,在shell下启动一个前台进程。

(2)用户按下ctrl+c通过鼠标形成一个硬件终端。
(3)假如cpu当前正在运行此进程的代码,则该进程的用户空间的代码将暂停执行cpu从用户态切换至内核态处理中断。
(4)终端驱动程序将ctrl+c解释为一个讯号,记在该进程的PCB中。
(5)当某个时刻从内核返回至该进程的用户空间代码继续执行之前,首先处理PCB中记录的讯号讯号的默认处理为中止讯号,所以直接中止进程而不再返回到它的用户空间代码讯号的捕捉处理
函数的功能是检测或更改与指定讯号相关联的处理动作。它是POSIX的讯号插口而是标准c的讯号插口信号与信息处理,
int sigaction(int signo, const struct sigaction *restrictact, struct sigaction *restrictoact);
第二第三参数为结构体
struct sigaction
{
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flag;
void (*sa_sigaction)(int,siginfo_t*,void*);
};
:包含一个讯号捕捉函数的地址
:是一个讯号集,在调用该讯号捕捉函数之前,这一讯号集要加进进程的讯号屏蔽字中即执行讯号处理函数期间,阻塞讯号屏蔽字中的讯号,执行结束后再处理这期间发生的讯号。阻塞的意思是延后讯号处理。
:是一个选项,这个选项只与函数注册的讯号关联,与中的讯号无任何关系。
/**
* brief CTRL + C等信号的处理函数,结束程序
*
* param signum 信号编号
*/
static void ctrlcHandler(int signum)
{
LOGTRACE("ctrlcHandler");
//如果没有初始化hService实例,表示出错
hService *instance = hService::serviceInstance();
instance->Terminate();
}
/**
* brief HUP信号处理函数
*
* param signum 信号编号
*/
static void hupHandler(int signum)
{
LOGTRACE("hupHandler");
//如果没有初始化hService实例,表示出错
hService *instance = hService::serviceInstance();
instance->reloadConfig();
}
int main()
{
//设置信号处理
struct sigaction sig;
sig.sa_handler = ctrlcHandler;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
sigaction(SIGINT, &sig, NULL);
sigaction(SIGQUIT, &sig, NULL);
sigaction(SIGABRT, &sig, NULL);
sigaction(SIGTERM, &sig, NULL);
sig.sa_handler = hupHandler;
sigaction(SIGHUP, &sig, NULL);
sig.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sig, NULL);
return 0;
}
