"EAGAIN"或"EWILLBLOCK"之间的区别



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

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

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

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

对于大多数系统,EAGAINEWOULDBLOCK是相同的。 只有少数系统是不同的,您可以在此答案中看到这些系统的列表。

甚至 errno 手册也提到它们"可能是相同的 [值]"。

然而,从历史上看,EWOULDBLOCK被定义为"操作将阻止",也就是说,操作阻止,但描述符被置于非阻塞模式。EAGAIN最初表示"暂时的资源短缺使行动无法进行"时表示。 GNU 文档使用的示例是当没有足够的资源来fork()时。 由于预计资源短缺是暂时的,因此随后尝试执行该操作可能会成功(因此称为"再次")。

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

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

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

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

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

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

#define EWOULDBLOCK EAGAIN  /* Operation would block */

最新更新