Gre*_*era 12 c sockets nonblocking recv posix-select
我看过一些select()与poll()or相比的文章epoll(),我看到很多指南讨论了select()多个套接字的实际用法.
但是,我似乎无法找到的是与没有阻塞的无阻塞recv()呼叫的比较select().如果只有1个套接字要读取,1个套接字要写入,是否有任何理由使用该select()呼叫?该recv()方法可以设置为WSAEWOULDBLOCK在没有可用数据的情况下不阻塞并返回错误(),那么select()当您没有其他套接字要检查时,为什么还要打扰?非阻塞recv()调用是否慢得多?
goj*_*oji 10
如果没有其他方法等待套接字上的数据,你就不会想要一个非阻塞调用recv,因为你无限制地轮询cpu时间.
如果您没有其他套接字要检查,并且在同一个线程中没有其他任何操作,则阻塞调用read可能是最有效的解决方案.虽然在这种情况下,考虑到这种效率就像是过早优化.
随着套接字数量的增加,这些考虑因素只会发挥作用.
非阻塞调用仅在处理单个线程上的多个套接字的上下文中更快.
如果没有可用数据,并且您使用非阻塞 IO,recv()则会立即返回。那么程序应该怎么做呢?您需要recv()在循环中调用直到数据可用 - 这几乎没有理由地使用 CPU。
recv()以这种方式启动和烧毁 CPU 是非常不可取的;你宁愿让进程等到数据可用并被唤醒;这就是select()/poll()和类似的。
而且,sleep()在循环中为了不烧CPU也不是一个好的解决办法。您会在处理过程中引入高延迟,因为一旦数据可用,程序将无法处理数据。
select()和朋友一起让你设计工作流程,使得一个插槽的缓慢不会妨碍你为另一个插槽服务的速度.想象一下,数据从接收套接字快速到达,并且您希望尽可能快地接受它并存储在内存缓冲区中.但发送套接字很慢.当你已经填满操作系统的发送缓冲区并send()给你EWOULDBLOCK时,你可以发出select()来等待接收和发送套接字.select()如果接收套接字上的新数据到达,或者某些缓冲区被释放,您可以将更多数据写入发送套接字,以先发生者为准.
当然,更实际的用例select()是当您有多个套接字要读取和/或写入时,或者必须在两个方向上的两个套接字之间传递数据时.
实际上,select()告诉您何时知道套接字上的下一个读取或写入操作是否成功,所以如果您只在select允许的情况下尝试读取和写入,即使您没有使套接字成为非套接字,您的程序也几乎可以正常工作阻挡!这样做仍然是不明智的,因为尽管select()报告套接字为"就绪",但是当下一个操作仍然可能阻塞时存在边缘情况.
另一方面,select()由于@Troy解释的原因,使插座无阻塞而不使用几乎是不可取的.