面试题答案
一键面试1. libev库中异步信号处理机制的基本工作流程
- 初始化信号监控:
- 使用
ev_signal_init
函数初始化一个ev_signal
类型的监控器。该函数接受三个参数,分别是指向ev_signal
结构体的指针、一个回调函数指针,以及要监控的信号编号。例如,要监控SIGTERM
信号,可以这样初始化:
其中ev_signal sig_watcher; ev_signal_init(&sig_watcher, signal_callback, SIGTERM);
signal_callback
是自定义的回调函数,当接收到指定信号时会被调用。 - 使用
- 将信号监控器添加到事件循环:
- 使用
ev_signal_start
函数将初始化好的信号监控器添加到ev_loop
事件循环中。例如:
这样,libev库就开始监控指定的信号了。ev_loop *loop = EV_DEFAULT; ev_signal_start(loop, &sig_watcher);
- 使用
- 信号触发与回调:
- 当被监控的信号(如
SIGTERM
)发生时,libev库会调用在初始化时指定的回调函数。在回调函数中,可以编写处理该信号的逻辑,比如关闭打开的文件描述符、释放内存、停止其他线程等。
- 当被监控的信号(如
2. 在实际应用场景中使用libev的异步信号处理确保程序优雅关闭
- 编写信号回调函数:
- 在回调函数中实现优雅关闭的逻辑。例如:
static void signal_callback(struct ev_loop *loop, ev_signal *w, int revents) { // 停止相关的业务逻辑,比如关闭网络连接 close(socket_fd); // 释放分配的内存 free(buffer); // 停止事件循环 ev_break(loop, EVBREAK_ALL); }
- 初始化和启动信号监控:
- 按照上述基本工作流程,初始化并启动对
SIGTERM
信号的监控。完整示例代码如下:
在这个示例中,程序在接收到#include <ev.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> // 假设这是一个打开的文件描述符 int socket_fd; char *buffer; static void signal_callback(struct ev_loop *loop, ev_signal *w, int revents) { printf("Received SIGTERM, starting graceful shutdown...\n"); close(socket_fd); free(buffer); ev_break(loop, EVBREAK_ALL); } int main() { ev_loop *loop = EV_DEFAULT; ev_signal sig_watcher; socket_fd = open("test.txt", O_RDONLY); buffer = (char *)malloc(1024); ev_signal_init(&sig_watcher, signal_callback, SIGTERM); ev_signal_start(loop, &sig_watcher); printf("Press Ctrl + C to send SIGTERM\n"); ev_run(loop, 0); printf("Graceful shutdown completed\n"); free(buffer); return 0; }
SIGTERM
信号时,会关闭文件描述符、释放内存,并停止事件循环,从而实现优雅关闭。 - 按照上述基本工作流程,初始化并启动对