【问题标题】:Difference between 'EAGAIN' or 'EWOULDBLOCK'“EAGAIN”或“EWOULDBLOCK”之间的区别
【发布时间】:2018-03-01 12:07:19
【问题描述】:

我需要了解 EAGAIN 和 EWOULDBLOCK 之间的区别,因为我已经看到许多源代码仅针对 EAGAIN 进行检查(可能两个代码都代表相同的数字,请在此处纠正我。)

我的部分知识: 如果发送方缓冲区已满且接收方未接收任何数据,则阻塞套接字,如果调用 send(),发送方将被挂起。这是因为一旦数据被接收器读取,它在缓冲区中使用的空间就可用于新数据。如果您的套接字处于“非阻塞”模式,则“send()”将失败并显示“EAGAIN”或“EWOULDBLOCK”。

它们是否总是相同的数字,或者是否存在需要区别对待的任何情况。 ?

【问题讨论】:

  • 两个符号常量的原因可能是历史性的,现在它们根本不应该被区别对待(并且在 IP 堆栈的大多数实现中不能,因为它们被定义为相同数值)。如果您想了解更多信息,那么将您的标题放入您最喜欢的搜索引擎应该足以让您阅读。

标签: sockets tcp operating-system


【解决方案1】:

简而言之:它们几乎总是相同的值,但为了可移植性,建议检查这两个值(并以相同的方式处理这两个值)。

对于大多数系统,EAGAINEWOULDBLOCK 将是相同的。只有少数系统不同,您可以查看这些系统的列表in this answer

甚至errno manpage 也提到它们“可能是相同的[值]”。

然而,从历史上看,EWOULDBLOCK 被定义为“操作会阻塞”——也就是说,操作被阻塞,但描述符被置于非阻塞模式。 EAGAIN 最初表示“临时资源短缺使操作无法进行”。 gnu documentation 使用的示例是当fork() 没有足够的资源时。由于预计资源短缺是暂时的,因此执行该操作的后续尝试可能会成功(因此名称为“again”)。

实际上,这些类型的临时资源短缺并不常见(但确实发生时非常严重)。

大多数系统都将这些值定义为相同的值,而没有定义这些值的系统将来会变得越来越少见。尽管如此,出于可移植性的原因,您应该检查这两个值,但您也应该以相同的方式处理这两个错误。正如GNU documentation 所说:

可移植性 注意:在许多较旧的 Unix 系统中... [EWOULDBLOCK 是] 与 EAGAIN 不同的明显错误代码。为了使您的程序具有可移植性,您应该检查这两个代码并将它们一视同仁。

【讨论】:

    【解决方案2】:

    它们在功能上是相同的。两个不同名称的原因可以追溯到 1980 年代。 EWOULDBLOCK 用于 Unix 的 BSD/Sun 变体,EAGAIN 是 AT&T System V 错误代码。

    对于特定系统上的编译二进制文件,代码应该具有相同的值。在包含文件中定义这两个名称的原因是为了源代码的可移植性。

    【讨论】:

      【解决方案3】:

      它们是相同的。
      include/uapi/asm-generic/errno.h 文件中定义:

      #define EWOULDBLOCK EAGAIN  /* Operation would block */
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-21
        • 2017-05-09
        • 2011-10-23
        • 2016-11-07
        • 2017-06-09
        • 1970-01-01
        • 2011-09-09
        • 2020-12-06
        相关资源
        最近更新 更多