“EAGAIN”或“EWOULDBLOCK”之间的区别

问题描述 投票:0回答:3

我需要了解

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

我的部分知识: 对于阻塞套接字,如果发送方缓冲区已满并且接收方没有接收任何数据,如果调用

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

他们总是相同的数字还是在任何情况下需要对他们进行区别对待?

sockets tcp operating-system
3个回答
17
投票

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

对于大多数系统,

EAGAIN
EWOULDBLOCK
是相同的。 只有少数系统不同,您可以看到这些系统的列表在此答案中

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

然而,历史上,

EWOULDBLOCK
被定义为“操作将阻塞”——也就是说,操作would已经阻塞,但描述符被置于非阻塞模式。
EAGAIN
最初表示“临时资源短缺导致操作无法进行”。 gnu 文档使用的示例是当没有足够的资源来
fork()
时。 由于预计资源短缺是暂时的,因此后续尝试执行该操作可能会成功(因此称为“再次”)。

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

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

可移植性注意事项:在许多较旧的 Unix 系统中... [EWOULDBLOCK 是] 与 EAGAIN 不同的明显错误代码。为了使您的程序可移植,您应该检查这两个代码并对它们进行相同的处理。


5
投票

它们的功能相同。这两个不同名称的历史渊源可以追溯到 20 世纪 80 年代。 EWOULDBLOCK 用于 Unix 的 BSD/Sun 变体,EAGAIN 是 AT&T System V 错误代码。

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


-2
投票

它们是一样的。
定义在

include/uapi/asm-generic/errno.h
文件中:

#define EWOULDBLOCK EAGAIN  /* Operation would block */
© www.soinside.com 2019 - 2024. All rights reserved.