EAGAIN' EAGAIN'之间的区别或者' EWOULDBLOCK'

时间:2018-03-01 12:07:20

标签: sockets tcp operating-system

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

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

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

3 个答案:

答案 0 :(得分:2)

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

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

即使errno manpage提及他们“可能是相同的[值]”。

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

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

大多数系统将这些值定义为相同,未来的系统将变得越来越罕见。然而,出于可移植性的原因,您应该检查两个值,但是您也应该以相同的方式处理这两个错误。正如GNU documentation所述:

  

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

#define EWOULDBLOCK EAGAIN  /* Operation would block */