慢速系统调用会被捕获信号中断
一、慢速系统调用可能造成进程永久阻塞
慢速系统调用包括:
1、在读某些类型的文件(管道、终端设备以及网络设备)时,如果数据不存在,则调用者永远阻塞。
说明:
管道:如果创建了一对读写管道,如果写管道始终没有写数据,而读管道进程就会被阻塞。
终端设备:如果要从终端read,但却没有输入,那么阻塞
网络设备:如果要读数据,对端未准备好数据,则阻塞
2、在写这些类型的文件,如果不能立即接受这些数据,则调用者会阻塞
3、打开某些类型的文件,在某种条件发生之前也可能会使调用者阻塞(如采用MODEM远程登陆的情况)
4、pause和wait函数
5、某些ioctl函数
6、某些进程间通信函数
二、慢速系统调用会被捕捉到的信号中断
当进程设置了某个信号的处理函数时意味着需要处理这个函数,此时就会中断阻塞的程序去进行处理函数。
ioctal、read、readv、write和writev只对低速设备进行操作时会被信号中断。
wait和waitpid在捕捉到信号时总是被中断,中断时产生EINTR错误,所以多线程中使用wait和waitpid等待多个子线程时可能需要判断EINTR错误。例如SIGCHLD,系统自动处理此信号,所以不设置重启动。
while(waitpid(pid,&stat,0)<0) if(errno!=EINTR) return -1;
同时Linux支持被中断的系统调用的自动重启动,在sigaction的struct sigaction里的sa_flags字段中设置SA_RESTART可以使被中断的系统调用自动重启。而使用signal设置信号处理函数时,是否重启动则根据不同系统的具体实现。所以尽量使用sigaction设置处理函数。