我需要了解EAGAIN和EWOULDBLOCK之间的区别,因为我看到很多源代码只针对EAGAIN进行检查(可能两个代码都代表相同的数字,请在此处更正。)
我的知识部分: 对于阻塞套接字,如果发送方缓冲区已满且接收方未接收任何数据,则发送方将在调用send()时被挂起。这是因为一旦接收器读取了数据,它在缓冲区中使用的空间就可用于新数据。如果您的套接字处于“无阻塞”状态,模式然后' send()'将失败的' EAGAIN'或者' EWOULDBLOCK'。
它们是否始终是相同的数字,或者是否存在需要区别对待的情况。 ?
答案 0 :(得分:2)
简而言之:它们几乎总是相同的值,但为了便携性,建议检查两个值(并以相同的方式处理这两个值)。
对于大多数系统,EAGAIN
和EWOULDBLOCK
都是相同的。只有少数几个系统不同,您可以看到这些系统的列表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 */