《UNIX环境高级编程》笔记--中断的系统调用
来源:互联网 发布:电磁波检测软件 编辑:程序博客网 时间:2024/06/04 23:15
早期的UNIX系统的一个特性是:如果进程在执行一个低速系统调用而阻塞期间捕捉到一个信号,该系统调用就被终端不再
继续执行。该系统调用返回出错,其errno被设置为EINTR。
为了支持这种特性,将系统调用分成两类:低速系统调用和其他系统调用。低速系统调用是可能会使进程永远阻塞的一类
系统调用:
1.在读某些类型的文件(管道,终端设备以及网络设备)时,如果数据并不存在则可能会使调用者永远阻塞。
2.在写这些类型的文件时,如果不能立即接受这些数据,则会使调用者永远阻塞。
3.打开某些类型的文件,在某些条件发生之前也可能会使调用者阻塞(例如,打开终端设备,它要等待直到所连接的调制
解调器应答了电话)
4.pause函数和wait函数
5.某些ioctl函数
6.某些进程间通信函数。
与被中断的系统调用相关的问题是必须显式地处理出错返回。典型的代码如下:
again:if((n=read(fd,buf,BUFFSIZE))<0){if(errno == EINTR)goto again;}为了帮助应用程序使其不必处理被中断的系统调用,4.2BSD引入了某些中断系统调用的自动重启动。自动重启动的系统调用包括:
ioctl,read,readv,write,writev,wait和waitpid。其中前5个函数只有对低速设备进行操作时才会被信号终端。而wait和waitpid
在捕捉到信号时总是被终端。
POSIX.1允许实现重启动系统调用,但是这并不是必须的。XSI将SA_RESTART定义为对sigaction的XSI扩展,允许应用程序要求
重启被中断的系统调用。
实践:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <stdbool.h>#include <signal.h>#include <sys/types.h>#include <errno.h>#include <string.h>void int_handler (int signum){ printf ("int handler %d\n",signum);}int main(int argc, char **argv){ char buf[100]; ssize_t ret; struct sigaction oldact; struct sigaction act; act.sa_handler = int_handler; act.sa_flags=0; // act.sa_flags |= SA_RESTART; sigemptyset(&act.sa_mask); if (-1 == sigaction(SIGINT,&act,&oldact)) { printf("sigaction failed!\n"); return -1; } bzero(buf,100); ret = read(STDIN_FILENO,buf,10); if (ret == -1) { printf ("read error %s\n", strerror(errno)); } printf ("read %d bytes, content is %s\n",ret,buf); sleep (10); return 0;}运行结果:
root@-virtual-machine:~# ./a.out
^Cint handler 2
read error Interrupted system call
read -1 bytes, content is
root@virtual-machine:~#
可见read直接返回,不会重启。
下面我们将
act.sa_flags |= SA_RESTART;
的注释打开,再次运行:
root@virtual-machine:~# ./a.out
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
123
read 4 bytes, content is 123
root@virtual-machine:~#
按了多次ctrl c,read也没有返回,因为read自动重启了。
- 《UNIX环境高级编程》笔记--中断的系统调用
- Unix环境高级编程(阅读笔记)----中断的系统调用,自动重启动的函数
- 《UNIX环境高级编程》笔记--系统标识
- 《UNIX环境高级编程》笔记--系统标识
- 《UNIX环境高级编程》的笔记
- UNIX环境高级编程——Linux系统调用列表
- UNIX环境高级编程——Linux系统调用列表
- 《 Unix环境高级编程 》笔记
- 《 Unix环境高级编程 》笔记
- 《 Unix环境高级编程 》笔记
- Unix环境高级编程 笔记
- Unix环境高级编程笔记
- UNIX环境高级编程学习笔记(四)不调用fcntl函数实现dup2的功能
- unix环境高级编程笔记--高级IO
- Unix环境编程学习笔记------查看系统调用号文件
- 《UNIX环境高级编程》笔记--进程的终止
- 《UNIX环境高级编程》笔记--线程的同步
- 《UNIX环境高级编程》笔记--线程的取消选项
- golang实现base64加密解密
- Comparator和Comparable在排序中的应用
- 用CSplitterWnd类分割窗体
- 新手如何学习ExtJS 4
- Python入门教程 超详细1小时学会Python
- 《UNIX环境高级编程》笔记--中断的系统调用
- long 和 int
- IE.火狐中href 兼容的注意事项 ,应用中的删除自己所在行数据,在IE上可用,在FF,谷歌等不可用的问题
- NSUserdefault 存储自定义对象
- spicce资料收集
- linux教程:Git使用技巧篇
- 100个高质量Java开发者博客 【转】
- 万事都有一个平衡
- 渐难自拔——一个屌丝极客的比特币挖矿日记