当前位置: 首页 > news >正文

如何理解SA_RESTART”被信号中断的系统调用自动重启“?

"被信号中断的系统调用自动重启"是 Linux 信号处理中的一个重要机制,由 SA_RESTART 标志控制。以下是深入解释:

核心概念

当进程执行阻塞型系统调用(如 read(), write(), accept(), wait() 等)时:

  1. 如果系统调用执行期间收到信号
  2. 该信号设置了信号处理函数(非忽略/默认终止)
  3. 系统调用会被中断,立即返回用户空间执行信号处理函数

此时系统调用有两种后续处理方式:

  • 不自动重启:系统调用返回 -1,并设置 errno = EINTR(被中断)
  • 自动重启(设置 SA_RESTART):内核自动重新执行被中断的系统调用

工作流程对比

有信号
已设置
未设置
阻塞系统调用开始
信号到达
中断系统调用
执行信号处理函数
SA_RESTART 标志
内核自动重启系统调用
返回用户空间 errno=EINTR
系统调用完成
应用程序处理 EINTR

实际代码示例

未设置 SA_RESTART 的情况

#include <stdio.h>
#include <unistd.h>
#include <signal.h>void handler(int sig) {printf("Received signal %d\n", sig);
}int main() {struct sigaction sa;sa.sa_handler = handler;sigemptyset(&sa.sa_mask);sa.sa_flags = 0; // 不设置 SA_RESTARTsigaction(SIGINT, &sa, NULL);char buf[256];ssize_t n = read(STDIN_FILENO, buf, sizeof(buf)); // 阻塞读if (n == -1 && errno == EINTR) {printf("Read interrupted!\n");}return 0;
}

当按下 Ctrl+C(发送 SIGINT)时:

  1. read() 被中断
  2. 执行信号处理函数
  3. read() 返回 -1errno = EINTR

设置 SA_RESTART 的情况

sa.sa_flags = SA_RESTART; // 关键设置

同样按下 Ctrl+C 后:

  1. read() 被中断
  2. 执行信号处理函数
  3. 内核自动重启 read() 调用
  4. 程序继续阻塞等待输入

技术细节

  1. 哪些系统调用支持重启

    • 文件I/O:read, write, open
    • 进程控制:wait, waitpid
    • 网络操作:accept, connect, recv
    • 不支持的:poll, select, epoll_wait(需手动处理 EINTR)
  2. 重启的实现位置
    在 Linux 内核源码 kernel/signal.cget_signal() 函数中:

    if (sig_handler_ignored(...) || (sa->sa_flags & SA_RESTART)) {restart_syscall(); // 重启逻辑
    }
    
  3. 编程最佳实践

    • 对需要可靠性的服务程序,建议设置 SA_RESTART
    • 对需要快速响应信号的程序(如监控),避免使用 SA_RESTART
    • 即使使用 SA_RESTART,也应处理关键操作的 EINTR:
      do {ret = accept(sockfd, ...);
      } while (ret == -1 && errno == EINTR); // 安全重启
      

典型应用场景

  1. 网络服务器

    sa.sa_flags = SA_RESTART; // 确保accept不会因信号失败
    sigaction(SIGCHLD, &sa, NULL); // 处理子进程退出
    

    当子进程退出发送 SIGCHLD 时,accept() 自动重启

  2. 交互式程序

    sa.sa_flags = 0; // 不设置SA_RESTART
    sigaction(SIGALRM, &sa, NULL); // 超时信号
    

    read()SIGALRM 中断时,可执行超时处理逻辑

这种机制平衡了系统调用的可靠性和信号的响应能力,是 Linux 信号处理体系的核心设计之一。

http://www.lryc.cn/news/615131.html

相关文章:

  • SELinux 入门指南
  • ROS2 多线程 与组件机制
  • Python NumPy入门指南:数据处理科学计算的瑞士军刀
  • Qt 的对象线程亲和性规则
  • 华为欧拉OpenEnler系统在启动MindIE时权限问题的解决方法
  • 从灵感枯竭到批量产出:无忧秘书创作平台如何重构内容生产者的工作流程?全环节赋能分析
  • Spring Boot 集成 Quartz 实现定时任务(Cron 表达式示例)
  • WinForm 中 ListView 控件的实战应用与功能拓展
  • kafka架构原理快速入门
  • AI大语言模型在生活场景中的应用日益广泛,主要包括四大类需求:文本处理、信息获取、决策支持和创意生成。
  • 软件定义车辆加速推进汽车电子技术
  • Blender 快捷键速查表 (Cheat Sheet)
  • 【线性代数】6二次型
  • 可直接运行的 Playwright C# 自动化模板
  • 通过 Certimate 统一管理 SSL 证书 支持自动化申请、全平台部署
  • 【线性代数】线性方程组与矩阵——(1)线性方程组与矩阵初步
  • 数据挖掘2.6 Perceptron Modeling 感知器建模
  • 我想做自动化报社保,用哪种技术更好一点呢?
  • stm32项目(25)——基于stm32的植物生长箱环境监测系统
  • 「iOS」————响应者链与事件传递链
  • GPT-5:数字大脑的进化史
  • 人工智能-python-数据处理实战-特征降维(PCA)
  • CD63.【C++ Dev】多态(2): 剖析虚函数表的前置知识
  • 【线性代数】线性方程组与矩阵——(3)线性方程组解的结构
  • 【CTF】PHP反序列化基础知识与解题步骤
  • 华为实验:SSH
  • 华为实验: 单区域/多区域OSPF
  • [优选算法专题一双指针——四数之和]
  • 【Leecode 随笔】
  • 大模型在垂直场景的创新应用:搜索、推荐、营销与客服新玩法