gpt4 book ai didi

c++ - 当服务器速度慢时,写入客户端返回 EWOULDBLOCK

转载 作者:可可西里 更新时间:2023-11-01 02:34:52 26 4
gpt4 key购买 nike

我试图在特定时间间隔后在套接字中写入一些数据。我有两个线程,一个线程维护 TCP 连接,另一个线程生成数据。

The data generation therad生成数据,并将其写入共享内存。服务器线程从共享内存中读取数据,发送给客户端。

但是,当数据生成线程变慢时,当涉及大量计算时,服务器线程在尝试写入客户端时会出现 EWOULDBLOCK 错误。但是,令人惊讶的是,从客户端来看,并没有这样的错误。

如果我没记错的话,当服务器比客户端快并且套接字缓冲区在再次写入之前未完全读取时,将返回 EWOULDBLOCK 错误。但是,这里的情况完全相反。

会不会是server therad一直处于休眠状态,直到数据生成线程完成(数据线程优先级高)

有人可以解释这里可能发生的事情吗?

最佳答案

当您使用非阻塞套接字并且内核的传出数据缓冲区中没有足够的空间供该套接字保存您要发送的任何数据时,将返回 EWOULDBLOCK。如果客户端读取速度太慢,可能会发生这种情况,但如果服务器试图一次发送大量数据,也可能会发生这种情况(即使使用快速客户端);例如,如果你的计算线程花了很长时间计算数据,然后在计算结束时突然一次传递了超过 300,000 字节的数据,你的服务器线程可能会做这样的事情:

  1. 看到共享内存区域中有一些数据可用,是时候开始发送了!
  2. 使用 len=300000 调用 send()。 send() 吸收尽可能多的数据,因为它可以放入内核的传出套接字数据缓冲区(例如 131,072 字节)并返回 131072 以指示它已完成的操作。
  3. 现在您的服务器线程发现它还有 168928 字节的数据要发送,所以它再次调用 send() 并设置 len=168928。此时,内核的传出套接字数据缓冲区仍然完全满(因为还没有机会发送任何数据包),因此 send() 返回 EWOULDBLOCK。

一般来说,只要您使用的是非阻塞套接字,EWOULDBLOCK 就是您的代码需要处理的内容。我通常的处理方式是:

  1. 在 select()(或 poll() 等)内部等待,直到套接字返回准备好写入
  2. 当 select()/poll() 指示套接字准备好写入时,调用套接字上的 send() 直到您发送了所有可用数据,或者直到 send() 返回 EWOULDBLOCK(以哪个为准首先)。
  3. 如果您在第 2 步中得到 EWOULDBLOCK,请转到 1。

这样你的发送线程将总是尽可能快地将传出数据提供给内核,但不会更快——也就是说你不会浪费任何 CPU 做忙循环,但你也不会浪费时间在流程中插入任何不必要的延迟。

关于c++ - 当服务器速度慢时,写入客户端返回 EWOULDBLOCK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16281468/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com