ppa*_*dey 9 sockets operating-system tcp
我需要了解 EAGAIN 和 EWOULDBLOCK 之间的区别,因为我看到许多源代码仅针对 EAGAIN 进行检查(可能两个代码代表相同的数字,请在此处纠正我。)
我的部分知识:如果发送方缓冲区已满且接收方未接收任何数据,则用于阻塞套接字,如果调用 send(),发送方将被挂起。这是因为一旦接收器读取数据,它在缓冲区中使用的空间就可用于新数据。如果您的套接字处于“非阻塞”模式,则“send()”将失败并显示“EAGAIN”或“EWOULDBLOCK”。
它们是否总是相同的数字,或者是否存在需要区别对待的情况。?
简而言之:它们几乎总是相同的值,但为了可移植性,建议检查这两个值(并以相同的方式处理这两个值)。
对于大多数系统,EAGAIN
和EWOULDBLOCK
将是相同的。只有少数系统不同,您可以在此答案中查看这些系统的列表。
甚至errno 联机帮助页也提到它们“可能是相同的 [值]”。
然而,从历史上看,它EWOULDBLOCK
被定义为“操作会阻塞”——也就是说,操作会被阻塞,但描述符被置于非阻塞模式。 EAGAIN
最初表示“临时资源短缺导致无法进行操作”。gnu 文档使用的示例是当没有足够的资源来fork()
. 由于预计资源短缺是暂时的,因此后续尝试执行该操作可能会成功(因此名称为“再次”)。
实际上,这些类型的临时资源短缺并不常见(但发生时非常严重)。
大多数系统将这些值定义为相同的值,不相同的系统在未来会越来越少见。尽管如此,出于可移植性的原因,您应该检查两个值,但您也应该以相同的方式处理这两个错误。正如GNU 文档所述:
可移植性说明:在许多较旧的 Unix 系统中... [EWOULDBLOCK 是] 与 EAGAIN 不同的明显错误代码。为了使您的程序可移植,您应该检查两个代码并将它们视为相同的。
小智 5
它们在功能上是相同的。这两个不同名称的历史渊源可以追溯到 20 世纪 80 年代。EWOULDBLOCK 用于 Unix 的 BSD/Sun 变体,EAGAIN 是 AT&T System V 错误代码。
对于特定系统上编译的二进制文件,代码应该具有相同的值。在包含文件中定义这两个名称的原因是为了源代码的可移植性。