SIGALRM信号处理机制详解

SIGALRM信号处理机制详解

1. 信号处理流程

cpp 复制代码
// 信号处理函数
void Utils::sig_handler(int sig)
{
    // 为保证函数的可重入性,保留原来的errno
    int save_errno = errno;
    int msg = sig;
    send(u_pipefd[1], (char *)&msg, 1, 0);
    errno = save_errno;
}

当SIGALRM信号发生时:

  1. 保存errno:保证信号处理函数的可重入性
  2. 发送信号到管道:将信号编号通过管道发送给主线程
  3. 恢复errno:恢复原来的错误状态

2. 定时器处理核心

cpp 复制代码
// 定时处理任务,重新定时以不断触发SIGALRM信号
void Utils::timer_handler()
{
    LOG_INFO << "in timer_handler: call m_timer_list.tick(): ";
    m_timer_list.tick();
    alarm(m_TIMESLOT);
}

3. 定时器链表处理

cpp 复制代码
void sort_timer_list::tick() // 定时任务处理函数
{
    LOG_TRACE << "tick: head " << head;
    if (!head)
    {
        return;
    }

    time_t cur = time(NULL);
    util_timer *tmp = head;
    while (tmp)
    {
        if (cur < tmp->expire) // cur当前时间小于定时器的过期时间,说明后面的定时器也没有到期
        {
            break;
        }
        LOG_INFO << "while(tmp): tmp user_data->sockfd: " << tmp->user_data->sockfd;
        tmp->cb_func(tmp->user_data);
        head = tmp->next;
        if (head)
        {
            head->prev = NULL;
        }
        delete tmp;
        tmp = head;
    }
}

4. 回调函数处理超时连接

cpp 复制代码
void cb_func(client_data *user_data)
{
    LOG_INFO << "user_data: " << user_data->sockfd;
    LOG_INFO << " epoll_ctl(Utils::u_epollfd, EPOLL_CTL_DEL, user_data->sockfd, 0)";
    epoll_ctl(Utils::u_epollfd, EPOLL_CTL_DEL, user_data->sockfd, 0);
    assert(user_data);
    close(user_data->sockfd);

    http_conn::m_user_count--;
    LOG_INFO << "http_conn::m_user_count: " << http_conn::m_user_count;
}

完整的事件处理流程

1. 信号设置

复制代码
utils.addsig(SIGALRM, utils.sig_handler, false);
  • SIGALRM:定时器信号,用于周期性触发
  • utils.sig_handler:自定义信号处理函数
  • false:不自动重启被中断的系统调用

2. 定时器初始化

每个新连接建立时创建定时器:

复制代码
time_t cur = time(nullptr);
timer->expire = cur + 3 * TIMESLOT;  // 设置3倍时间片后过期
utils.m_timer_list.add_timer(timer);

3. 周期性处理

  1. SIGALRM信号触发utils.sig_handler
  2. 信号通过管道传递 → 主线程epoll监听到管道可读
  3. 调用utils.timer_handler() → 处理超时连接
  4. 重新设置alarm → 继续周期性触发

4. 主要功能

🔍 连接超时检测
  • 检测空闲或异常连接
  • 防止资源泄漏
🧹 资源回收
  • 关闭超时连接的文件描述符
  • 从epoll实例中移除监控
  • 更新用户连接计数
心跳机制
  • 周期性检查连接状态
  • 确保服务器稳定性

5. 关键参数

  • m_TIMESLOT:定时器时间间隔(秒)
  • 3 * TIMESLOT:连接超时时间
  • restart=false:不自动重启系统调用,确保定时器精确性

总结

utils.addsig(SIGALRM, utils.sig_handler, false);实现了Web服务器的连接超时管理机制,通过周期性SIGALRM信号触发定时器检查,自动清理超时连接,是保证服务器稳定性和资源有效利用的关键组件。

SIGTERM信号处理详解

🔍 信号作用

SIGTERM(信号编号15)是终止进程信号,用于在类Unix操作系统中请求一个进程优雅地终止。

📋 处理机制

从代码中可以看到完整的处理流程:

cpp 复制代码
// 信号处理函数
case SIGTERM: // SIGTERM是一种信号,用于在类 Unix 操作系统中请求一个进程终止
    stop_server = true;
    break;

🔄 完整处理流程

  1. 信号注册

    复制代码
    utils.addsig(SIGTERM, utils.sig_handler, false);
  2. 信号传递

    • 当收到SIGTERM信号时,utils.sig_handler函数被调用
    • 信号通过管道发送给主线程:send(u_pipefd[1], (char *)&msg, 1, 0)
  3. 主线程处理

    cpp 复制代码
    bool WebServer::dealwithsignal(bool &timeout, bool &stop_server)
    {
        // 从管道读取信号
        ret = recv(m_pipefd[0], signals, sizeof(signals), 0);
        
        switch (signals[i]) {
        case SIGTERM:
            stop_server = true;  // 设置停止服务器标志
            break;
        }
    }
  4. 服务器停止

    • eventLoop中检查stop_server标志
    • stop_server为true时,退出事件循环,优雅关闭服务器

🎯 主要用途

优雅关闭服务器
  • 允许服务器完成当前请求处理
  • 清理资源(关闭连接、释放内存)
  • 记录日志信息
与SIGKILL的区别
  • SIGTERM:允许程序进行清理工作后终止
  • SIGKILL:立即强制终止,无法被捕获或忽略

触发方式

在Linux系统中可以通过以下命令发送SIGTERM信号:

复制代码
kill -TERM <进程ID>
# 或简写
kill <进程ID>

🔧 配置参数

  • SIGTERM:终止进程信号(编号15)
  • utils.sig_handler:自定义信号处理函数
  • false:不自动重启被中断的系统调用

📊 与其他信号的对比

信号 编号 作用 处理方式
SIGTERM 15 优雅终止进程 允许清理资源
SIGALRM 14 定时器信号 处理超时连接
SIGPIPE 13 管道破裂 忽略,防止崩溃

总结

utils.addsig(SIGTERM, utils.sig_handler, false);实现了Web服务器的优雅关闭机制,当收到SIGTERM信号时,服务器会设置停止标志,在完成当前请求处理后安全退出,确保资源正确释放,是服务器稳定运行的重要保障。

相关推荐
Zaralike9 分钟前
Linux 服务器网络不通排查 SOP(标准操作流程)
linux·服务器·网络
云姜.20 分钟前
网络协议----OSI七层网络协议 和 TCP/IP四层(五层)网络协议
网络·网络协议
!chen31 分钟前
LabVIEW TCP Server端工具TCP通信
网络·tcp/ip·labview
枷锁—sha1 小时前
【SRC】SQL注入快速判定与应对策略(一)
网络·数据库·sql·安全·网络安全·系统安全
郝学胜-神的一滴1 小时前
深入解析C/S模型下的TCP通信流程:从握手到挥手的技术之旅
linux·服务器·c语言·网络·网络协议·tcp/ip
池央1 小时前
CANN 算子诊断与故障定位:oam-tools 在异构计算错误解析中的作用
网络
“αβ”1 小时前
数据链路层协议 -- 以太网协议与ARP协议
服务器·网络·网络协议·以太网·数据链路层·arp·mac地址
释怀不想释怀1 小时前
Linux网络基础(ip,域名)
linux·网络·tcp/ip
开开心心就好1 小时前
AI人声伴奏分离工具,离线提取伴奏K歌用
java·linux·开发语言·网络·人工智能·电脑·blender
子榆.2 小时前
CANN 性能分析与调优实战:使用 msprof 定位瓶颈,榨干硬件每一分算力
大数据·网络·人工智能