博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
系统调用与信号重启,好
阅读量:7227 次
发布时间:2019-06-29

本文共 2068 字,大约阅读时间需要 6 分钟。

这篇写的很好

 

UNIX系统编程,这本书中有大量的重启系统调用,例如下面的例子:选自P50,

pid_t r_wait(int *stat_loc){    int retval;    while(((retval = wait(stat_loc)) ==-1 && (errno == EINTR));    return retval;}

还有对read,write的重启操作。

 

UNP volume1中提到slow system call,UNP中的例子是accept系统调用,accept是服务器端接受网络客户端的连接,connect,将完成三次握手协议的连接返回。如果服务器打开了监听listen,但是始终没有客户端来连接connect,可以想见,accept就阻塞在此。这是一种比较好理解的阻塞型系统调用。

wait也是一种阻塞性的调用。

 

但是linux世界上还有另外一种东东,叫做信号,来处理突发事件。

 

一般来讲,一个系统调用,要么成功,要么失败,但是由于为了及时处理信号,出现了第三种情况,系统调用被信号中断,为了标识这种情况,错误码errno置为EINTR。

 

我们可以看到这种方式并不优美,程序员需要自己判断errno,如果被信号终端,那么还需要自己来重启系统调用。这是System V UNIX的实现方式。

 

BSD 内核想程序员之所想,急程序员之所急,采用了另外一种实现,就是如果中断系统调用,切换到用户态来执行信号处理程序,那么系统调用没有返回值,内核在信号处理函数结束后,自动重启系统调用。这种方式很贴心阿,程序员再也不用自己判断errno,然后重启系统调用了。

 

LINUX不愧是UNIX世界的杰出新秀,他通过SA_RESTART 就可以支持BSD方案。

 

 

#include
#include
#include
#include
#include
#include
pid_t r_wait(int *stat_loc){ int ret; while(((ret = wait(stat_loc)) == -1) ) { /*if(errno == EINTR) { fprintf(stderr,"may be interrupted by a signal,let wait again \n"); } else*/ { break; } } return ret;}void sig_alrm_func(){ printf("catch an alarm signal\n"); return;}int main(int argc,char** argv){ pid_t childpid; int i,n; struct sigaction act; if(argc != 2) { fprintf(stderr,"usage : test n \n",argv[0]); return -1; } n = atoi(argv[1]); act.sa_handler = sig_alrm_func; sigemptyset(&act.sa_mask); act.sa_flags = 0; // act.sa_flags |= SA_RESTART; sigaction(SIGALRM,&act,NULL); for(i = 0;i
<= 0) break; } if(childpid == 0 ) { sleep(50); } while(r_wait(NULL) >0) ; fprintf(stderr," i :%d process ID : %ld,\t parent ID :%ld \tchild ID : %ld\n", i,(long)getpid(),(long)getppid(),(long)childpid); return 0;}
View Code

 

 

原文中对比了三种方案。

 

第一种,是不判断EINTR.

第二种,是判断EINTR,然后重启。

第三种,是对于信号处理函数,sigaction,里面sa_flags 加上对 SA_RESTART的支持,这样被中断的系统调用就能够自动重启了。

 

 

注意,和sleep是不一样的。sleep是返回的秒数可能不足。

http://www.cnblogs.com/charlesblc/p/6434213.html

返回剩余的秒数,而不是errno=EINTR。

sleep的例子应该是,SIGALARM,因为本身sleep就是用SIGALARM实现的。

 

转载于:https://www.cnblogs.com/charlesblc/p/6492703.html

你可能感兴趣的文章
express + mock 让前后台并行开发
查看>>
30天自制操作系统-2
查看>>
小程序开发之路(一)
查看>>
Odoo domain写法及运用
查看>>
JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
查看>>
猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
查看>>
面试题:给你个id,去拿到name,多叉树遍历
查看>>
go append函数以及写入
查看>>
关于Java中分层中遇到的一些问题
查看>>
配置 PM2 实现代码自动发布
查看>>
android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
查看>>
iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
查看>>
诡异!React stopPropagation失灵
查看>>
Python_OOP
查看>>
个人博客开发系列:评论功能之GitHub账号OAuth授权
查看>>
mongodb--安装和初步使用教程
查看>>
ES6简单总结(搭配简单的讲解和小案例)
查看>>
text-decoration与color属性
查看>>
如何使用Mybatis第三方插件--PageHelper实现分页操作
查看>>
PyCharm搭建GO开发环境(GO语言学习第1课)
查看>>