带选择的非阻塞套接字

时间:2010-01-06 18:54:48

标签: c networking nonblocking

我不明白在select之后调用recv()之后,在非阻塞套接字上调用recv()与阻塞套接字之间的区别是什么,它已准备好进行读取。在我看来,无论如何,阻塞套接字永远不会阻止这种情况 另外,我听说使用非阻塞套接字的一个模型是在经过一段时间后尝试对它们进行调用(recv / send / etc),而不是使用像select这样的东西。与使用像select这样的东西相比,这种技术看起来既缓慢又浪费(但是,如上所述,我根本没有达到非阻塞的目的)。这在今天的网络编程中是否常见?

4 个答案:

答案 0 :(得分:3)

对于执行名为The C10K Problem的高容量I / O的所有不同选项有一个很好的概述。它对很多不同的选项进行了相当完整的调查,至少从2006年开始。

引用它,关于在非阻塞套接字上使用select的主题:

  

注意:记住内核的准备就绪通知只是一个提示,这一点尤为重要。当您尝试从中读取文件描述符时,它可能还没有准备好。这就是使用准备就绪通知时使用非阻塞模式的重要原因。

是的,您可以使用非阻塞套接字然后有一个循环,等待没有准备就绪,但与使用select或其中一个更现代的替换({{}相比,这是相当浪费的1}},epoll等)。我想不出为什么有人真的想要这样做的原因;所有kqueue类似选项都可以设置超时,因此您可以在一定时间后唤醒以执行某些常规操作。我想如果你正在做一些相当CPU密集的事情,比如运行视频游戏,你可能想要永远不要睡觉,而是继续计算,同时使用非阻塞套接字定期检查I / O.

答案 1 :(得分:1)

selectpollepollkqueue等设施针对多个套接字/文件描述符处理方案。想象一下,一个重载的网络服务器有数百个同时连接的套接字。你怎么知道什么时候到read以及从哪个套接字没有阻止一切?

答案 2 :(得分:0)

如果您在非阻塞套接字上调用read,如果自上次调用read后未收到任何数据,则会立即返回。如果您只有read,并且想要等到有可用数据,则必须busy wait。这会浪费CPU。

pollselect(和朋友)允许你睡觉,直到有数据要读(或写,或收到信号等)。

如果您正在做的唯一事情就是在该套接字上发送和接收,那么您也可以使用非阻塞套接字。当您在此期间有其他事情要做时,异步非常重要,例如更新GUI或处理其他套接字。

答案 3 :(得分:0)

对于您的第一个问题,这种情况没有区别。唯一的区别是当没有什么东西要读时它们会做什么。因为你在调用recv()之前检查它,你会发现没有区别。

对于第二个问题,我在所有库中看到它的方式是使用select,poll,epoll,kqueue来测试数据是否可用。 select方法是最老的,从性能角度来看是最不可取的(特别是对于管理大量连接)。