Linux 何时检查 EINTR 并重复函数调用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4959524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:47:50  来源:igfitidea点击:

When to check for EINTR and repeat the function call?

linuxeintr

提问by stefangachter

I am programming a user application for a embedded Linux system, and I am using the common functions such as open, close, read, ioctl, etc. for the devices. Now, I read about EINTR, indicates that the function was interrupted by a signal, but I am not sure about the implications. In all the example programs I have, sometimes it is done, e.g. ioctl(), sometimes it is not done, e.g. read(). So, I am a little bit confused.

我正在为嵌入式 Linux 系统编写用户应用程序,我正在使用设备的常用功能,例如打开、关闭、读取、ioctl 等。现在,我读到有关 EINTR 的信息,表明该函数被信号中断,但我不确定其含义。在我拥有的所有示例程序中,有时完成,例如 ioctl(),有时未完成,例如 read()。所以,我有点困惑。

When do I preferably check for EINTR and repeat the function call?

我什么时候最好检查 EINTR 并重复函数调用?

采纳答案by Yann Droneaud

See sigaction : http://pubs.opengroup.org/onlinepubs/009695399/functions/sigaction.html

见 sigaction :http: //pubs.opengroup.org/onlinepubs/009695399/functions/sigaction.html

SA_RESTART
  This flag affects the behavior of interruptible functions; that is, those 
  specified to fail with errno set to EINTR. If set, and a function specified 
  as interruptible is interrupted by this signal, the function shall restart 
  and shall not fail with EINTR unless otherwise specified. If the flag is not 
  set, interruptible functions interrupted by this signal shall fail with errno 
  set to EINTR.

By default, you have the SA_RESTART behavior, so you don't have to worry about EINTR, if you don't play with signals.

默认情况下,您具有 SA_RESTART 行为,因此如果您不使用信号,则不必担心 EINTR。

回答by Maxim Egorushkin

Is your application event driven? (Meaning its main loop include select()/epoll_wait()call).

你的应用程序是事件驱动的吗?(意思是它的主循环包括select()/epoll_wait()调用)。

In an event driven application you can block all signals and only unblock them for the duration of pselect()/epoll_pwait()call. This way the rest of your code never have to deal with EINTR.

在事件驱动的应用程序中,您可以阻止所有信号,并且仅在pselect()/epoll_pwait()通话期间取消阻止它们。这样,您的其余代码就不必处理 EINTR。

回答by lobosch

I had a similar problem when waiting for input from a named pipe with read().

在使用 read() 等待来自命名管道的输入时,我遇到了类似的问题。

I found an explanation and a useful macro for primitives in GNU libc documentation: TEMP_FAILURE_RETRY

我在GNU libc 文档中找到了对原语的解释和有用的宏:TEMP_FAILURE_RETRY

Example:

例子:

TEMP_FAILURE_RETRY (read_return = read((int)example_fifo, buffer, (size_t)n));
if (read_return==-1){
    fprintf(stderr, "reader.c: read_fifo: read(): %s \n", strerror(errno));
    fflush(stderr);
}

回答by R.. GitHub STOP HELPING ICE

I know this question is old but I think there's more to be said. To answer the specific question in the title: basically, never.

我知道这个问题很老,但我认为还有更多要说的。回答标题中的具体问题:基本上,从不

Aside from selectand poll, EINTRcan only happen if you've installed (either by mistake/not understanding how to use sigaction, or because you wantto be able to interrupt blocking operations) interrupting signal handlers. Looping to retry when a function fails with EINTRjust undoes that. Doing so is an old anti-pattern from the 80s and early to mid 90s when lots of operating systems were buggy and reportedly generated EINTRunder non-conforming circumstances, but these bugs are long gone.

除了selectand之外pollEINTR只有在您安装(错误地/不理解如何使用sigaction,或者因为您希望能够中断阻塞操作)中断信号处理程序时才会发生。当一个函数失败时循环重试EINTR只是撤消了那个。这样做是 80 年代和 90 年代早期到中期的一种旧的反模式,当时许多操作系统都有错误,据报道是EINTR在不符合规定的情况下生成的,但这些错误早已不复存在。

It is possible that, even in an application where you want to be able to interrupt things with signals, there is some code whose successful completion is so important that you can't treat EINTRas an error condition and return back to the caller without completing the operation. In such a circumstance, it might make sense to install a retry loop, but it's probably better to mask signals (at least the potentially-interrupting ones) during the operation and unmasks after it finishes.

有可能,即使在您希望能够用信号中断事物的应用程序中,也有一些代码的成功完成非常重要,以至于您不能将其EINTR视为错误条件并在未完成的情况下返回给调用者手术。在这种情况下,安装重试循环可能是有意义的,但最好在操作期间屏蔽信号(至少是潜在中断的信号)并在完成后取消屏蔽。