Linux被中断的系统如何调用详解
发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,前言慢系统调用,指的是可能永远无法返回,从而使进程永远阻塞的系统调用,比如无客户连接时的accept、无输入时的read都属于慢速系统调用。在Linux中,当阻塞于某个慢系统调用的进程捕获一个信号,则
千家信息网最后更新 2025年12月02日Linux被中断的系统如何调用详解
前言
慢系统调用,指的是可能永远无法返回,从而使进程永远阻塞的系统调用,比如无客户连接时的accept、无输入时的read都属于慢速系统调用。
在Linux中,当阻塞于某个慢系统调用的进程捕获一个信号,则该系统调用就会被中断,转而执行信号处理函数,这就是被中断的系统调用。
然而,当信号处理函数返回时,有可能发生以下的情况:
- 如果信号处理函数是用signal注册的,系统调用会自动重启,函数不会返回
- 如果信号处理函数是用sigaction注册的
- 默认情况下,系统调用不会自动重启,函数将返回失败,同时errno被置为EINTR
- 只有中断信号的SA_RESTART标志有效时,系统调用才会自动重启
下面我们编写代码,分别验证上述几种情形,其中系统调用选择read,中断信号选择SIGALRM,中断信号由alarm产生。
使用signal
#include#include #include #include void handler(int s){ printf("read is interrupt by signal handler\n"); return;}int main(){ char buf[10]; int nread = 0; signal(SIGALRM, handler); alarm(2); printf("read start\n"); nread = read(STDIN_FILENO, buf, sizeof(buf)); printf("read return\n"); if ((nread < 0) && (errno == EINTR)) { printf("read return failed, errno is EINTR\n"); } return 0;}

使用sigaction + 默认情况
#include#include #include #include void handler(int s){ printf("read is interrupt by signal handler\n"); return;}int main(){ char buf[10]; int nread = 0; struct sigaction act; sigemptyset(&act.sa_mask); act.sa_handler = handler; act.sa_flags = 0; //不给SIGALRM信号设置SA_RESTART标志,使用sigaction的默认处理方式 //act.sa_flag |= SA_INTERRUPT; //SA_INTERRUPT是sigaction的默认处理方式,即不自动重启被中断的系统调用 //实际上,不管act.sa_flags值为多少,只要不设置SA_RESTART,sigaction都是按SA_INTERRUPT处理的 sigaction(SIGALRM, &act, NULL); alarm(2); printf("read start\n"); nread = read(STDIN_FILENO, buf, sizeof(buf)); printf("read return\n"); if ((nread < 0) && (errno == EINTR)) { printf("read return failed, errno is EINTR\n"); } return 0;}

使用sigaction + 指定SA_RESTART标志
#include#include #include #include void handler(int s){ printf("read is interrupt by signal handler\n"); return;}int main(){ char buf[10]; int nread = 0; struct sigaction act; sigemptyset(&act.sa_mask); act.sa_handler = handler; act.sa_flags = 0; act.sa_flags |= SA_RESTART; //给SIGALRM信号设置SA_RESTART标志 sigaction(SIGALRM, &act, NULL); alarm(2); printf("read start\n"); nread = read(STDIN_FILENO, buf, sizeof(buf)); printf("read return\n"); if ((nread < 0) && (errno == EINTR)) { printf("read return failed, errno is EINTR\n"); } return 0;}
由于对被中断系统调用处理方式的差异性,因此对应用程序来说,与被中断的系统调用相关的问题是:
- 应用程序无法保证总是知道信号处理函数的注册方式,以及是否设置了SA_RESTART标志
- 可移植的代码必须显式处理关键函数的出错返回,当函数出错且errno等于EINTR时,可以根据实际需求进行相应处理,比如重启该函数
int nread = read(fd, buf, 1024);if (nread < 0){ if (errno == EINTR) { //read被中断,其实不应该算作失败,可以根据实际需求进行处理,比如重写调用read,也可以忽略它 } else { //read真正的读错误 }}总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
系统
处理
信号
函数
信号处理
标志
方式
实际
情况
代码
内容
就是
应用程序
程序
进程
需求
学习
应用
选择
阻塞
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络技术工程师入门到精通
ios终端软件开发
网络技术发明的时间
做好网络安全守护者
数据库入门基础知识课后答案
计算机网络技术求职专业
黑龙江电信服务器地址云空间
徐州java软件开发管理
广西网络安全审查办公室
服务器更改密钥点击无反应
数据库技术实验实训报告
软件开发招投标周期
项目部署到服务器供其他人打开
湖南用友软件开发公司
湖北生活网络安全教育图片
盛世云商网络技术有限公司
csgo服务器架
服务器后面的锁什么用途
jsp传数据库乱码
市网络安全大赛报名
数据库系统的5种安全性
音频软件开发工程师条件
高效清空数据库表数据
wow六零数据库
用数据库设计小型系统
组织软件开发能力
机顶盒服务器访问不了
ice服务器被炸前什么样
软件开发招投标周期
数据库还原时间怎么看