Linux被中断的系统如何调用详解
发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,前言慢系统调用,指的是可能永远无法返回,从而使进程永远阻塞的系统调用,比如无客户连接时的accept、无输入时的read都属于慢速系统调用。在Linux中,当阻塞于某个慢系统调用的进程捕获一个信号,则
千家信息网最后更新 2026年11月03日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安全错误
数据库的锁怎样保障安全
手磨咖啡
互联网巨头反垄断金融科技
重庆互联网络科技
互联网金融公司科技
上海万想互联网科技
济南和联互联网科技有限公司
贵州叶脉互联网科技有限公司所属行业
科技互联网大厂
晓花互联网科技有限公司网址
辽宁互联网新科技
深圳育鹏互联网科技有限公司招聘
中国科技创新与世界互联网大会
畅思互联网科技
卓翼科技产业互联网合作
云南省自由互联网科技有限公司
互联网营销推广黑科技
浙南科技城互联网大厦招聘
珠海东科互联网科技有限公司
国产互联网科技公司
互联网大会出现的黑科技
百单网互联网科技有限公司
中关村互联网 科技集团
互联网科技的
青岛互联网科技公司
互联网金融科技平台
哈尔滨新华互联网科技
华中科技有哪些互联网大佬
常德市电业局互联网科技部
科技互联网海报
工业互联网科技创业