信号中断的系统调用仍然需要完成

Sha*_*dor 11 c c++ unix interrupt eintr

许多系统调用都close( fd )可以被信号中断.在这种情况下,通常-1会返回并errno设置EINTR.

问题是做什么是正确的?说,我仍然希望fd关闭它.

我能想到的是:

while( close( fd ) == -1 )
  if( errno != EINTR ) {
    ReportError();
    break;
  }
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议更好/更优雅/标准的方式来处理这种情况吗?

更新:正如mux所注意到的,RESTART在安装信号处理程序时可以使用SA_ 标志.有人可以告诉我哪些功能可以保证在所有POSIX系统上都可以重启(不仅仅是Linux)?

iab*_*der 9

一些系统调用是可重启的,这意味着内核将在中断时重启调用,如果SA_RESTART在安装信号处理程序时使用了该标志,则signal(7)手册页说:

如果对信号处理程序中断了对以下某个接口的阻塞调用,则在使用SA_RESTART标志后,如果信号处理程序返回,则调用将自动重新启动 ; 否则呼叫将失败并显示错误EINTR:

它没有提到是否close()可重启,但它们是:

read(2),readv(2),write(2),writev(2),ioctl(2),open(2),wait(2),wait3(2),wait4(2),waitid(2),和waitpid,accept(2),connect(2),recv(2),recvfrom(2),recvmsg(2),send(2),sendto(2)和sendmsg(2)flock(2)和fcntl( 2)mq_receive(3),mq_timedreceive(3),mq_send(3)和mq_timedsend(3)sem_wait(3)和sem_timedwait(3)futex(2)

请注意,这些详细信息,特别是不可重新启动的调用列表,是特定于Linux的

我发布了一个相关的问题,关于哪些系统调用是可重启的,如果它是由某个POSIX指定的,它是由POSIX指定的,但它是可选的,所以你应该检查你的操作系统的不可重启调用列表,如果它不在那里它应该是重新启动.这是我的问题: 如何知道Linux系统调用是否可重启?

更新:关闭是一种特殊情况,它不能重新启动,不应在Linux中重试,请参阅此答案以获取更多详细信息:https: //stackoverflow.com/a/14431867/1157444

  • 你是从Linux系统上的`man signal(7)`得到的吗?如果是:此列表仅对Linux有效.在同一个手册页上,它表示:"*详细信息因Unix系统而异*" (2认同)