C 在接收缓冲区中累积数据,以防止epoll_等待慢速连接时出现繁忙等待
客户端发送的数据量足够大,互联网连接速度足够慢,这让我在C语言中的经典无阻塞服务器客户端设置中忙着等待 繁忙等待的详细原因是此过程C 在接收缓冲区中累积数据,以防止epoll_等待慢速连接时出现繁忙等待,c,sockets,epoll,C,Sockets,Epoll,客户端发送的数据量足够大,互联网连接速度足够慢,这让我在C语言中的经典无阻塞服务器客户端设置中忙着等待 繁忙等待的详细原因是此过程 我为客户端安装了EPOLLIN(用于接收数据的监视器) 客户端发送数据 epoll\u wait通知我有数据要读取(EPOLLIN) 正在恢复协同路由,正在消耗数据,需要更多数据才能完成此客户端EWoldblock并返回到1 上述过程将重复数分钟(由于互联网连接速度慢和数据量大)。它基本上只是一个无用的跳跃,除了消耗cpu时间外,没有做任何有意义的事情。此外,这有点
EPOLLIN
(用于接收数据的监视器)epoll\u wait
通知我有数据要读取(EPOLLIN
)epoll\u wait
的目的
因此,我想通过某种机制来避免这种繁忙的等待,这种机制确实会在接收缓冲区中累积数据,直到达到最小大小或自第一个字节到达后经过最大超时,然后才使用此客户端的epoll_wait
唤醒我
我首先查看了一下,我希望得到类似于TCP\u CORK
的东西,但是没有找到任何东西
然后,在第3步之后,我通过SIOCINQ
亲自研究并尝试实现它。问题是,由于步骤3,我又忙着等待了。将立即返回,因为数据可供读取。或者,我可以在3之后立即注销客户端,但这将阻止此特定客户端,直到epoll\u wait
从其他客户端返回
这是一个僵局,还是有任何解决上述问题的方法可以在接收缓冲区内以最小大小或最大时间累积数据,而不必等待?@ezgong和我详细讨论了这一点,我确信这不是问题(正如@user207421所指出的) 当我第一次读到这个问题时,我想他们可能担心的是少量的数据(比如说,一次16字节),这本来是值得研究的,但一旦发现它一次是4KB,这是如此的常规以至于不值得研究 有趣的是,串行I/O模块确实支持这一点,它的模式只有在有这么多字符可用或经过这么多时间后才会唤醒,但网络模块没有这种功能
唯一值得一提的是,如果有实际证据表明它正在以一种有意义的方式影响应用程序的响应性,而不是假设的数据包速率问题。它真的占用了那么多CPU时间,还是大部分时间都在等待?当数据可用时,您平均每次可以读取多少?我在日志中看到,它跳了很多。每次大约有4-8千磅的读数可用。这大约是调用
recv
的1-2倍,缓冲区大小为4096字节。总长度(我知道最多8 KiB)约为30-50 MiB。这使得上述过程重复了5000次以上。我不认为这是一个真正的问题,但这是你的问题:-)如果你在每次非EOF读取之后,在返回调用epoll之前增加1秒的睡眠时间,那么你基本上会迫使操作系统缓冲更多的时间,并且不让进程参与其中。这并不能真正回答如何让TCP堆栈做到这一点的问题,它确实让人感觉非常粗糙,但它可能会为您解决一个问题。让我们来看看。您已经在做的事情非常普遍。与接收到所有数据后对数据进行的处理相比,所涉及的开销是微不足道的。