Chinaunix首页 | 论坛 | 博客
  • 博客访问: 289077
  • 博文数量: 59
  • 博客积分: 2021
  • 博客等级: 大尉
  • 技术积分: 491
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-29 09:49
文章分类

全部博文(59)

文章存档

2011年(6)

2010年(11)

2009年(42)

我的朋友

分类: LINUX

2010-09-10 15:20:05

当进程正在执行一个低速系统调用且处于阻塞期间时,如果进程捕获到一个信号,则该调用被中断,不再继续执行。 该系统调用返回出错,起errono设置为EINTR。 因为发生信号, 进程捕捉到它, 这将是一个很好的机会来唤醒阻塞的系统调用。
    与被中断的系统调用相关的问题是必须显示的处理这种出错返回,判断出错是否是因为被信号中断导致,看系统是否支持自动重启,以及我们是否需要重启被信号中断的系统调用。
    如果系统不自动重启这些被中断的系统调用,而我们希望重启,通常有2种方法,一是通过出错后检查errno,这是比较通用的方法,如下:

again:
    if((n=read(fd,buf,BUFFSEZE))<0)
    {
        if(errno==EINTR) //改错误是因为被信号中断

            goto again;
    }


另一种方法是在sigaction中设置允许重新启动被特定信号中断的系统调用的标志SA_RESTART(有些系统可能不支持):act.sa_flags |= SA_RESTART;

    某些系统引入了某些被中断后自动重启动的系统调用,如ioctl,read,readv,write,writev...,但这也会带来一些问题,如果我们并不希望重启这些被中断的调用,这时可以通过sigaction禁止重启,act.sa_flags |= SA_INTERRUPT。

    上述只是针对可能被阻塞的低速的系统调用,如果系统调用执行时没有阻塞,则其不会被信号中断,即使这时发生了信号。如果是设置了非阻塞的系统调用,则不必考虑被信号中断的问题了。


阅读(3566) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~