慢速系统调用会被捕获信号中断

一、慢速系统调用可能造成进程永久阻塞

  慢速系统调用包括:

  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设置处理函数。

posted @ 2021-10-28 16:36  放不下的小女孩  阅读(204)  评论(0编辑  收藏  举报