![]() |
1
1
我相信你正在仔细构造你的fd集,只使用当前连接的描述符…?然后,对具有读取或异常/错误条件的对象(后者的区别在于BSD和Windows实现)迭代集合并只发出recv()。虽然它在功能上还可以(在概念上也可以说是优雅的),但在大多数实际应用程序中,在接收之前不需要偷看:即使您不确定消息的大小,并且知道可以从缓冲区偷看,也应考虑是否可以:
一点也不好。如果您保持单线程,那么您需要在select上放置一个0超时值,然后像疯了一样在listenig和客户机描述符中旋转。非常浪费CPU时间,会大大降低延迟。
(忽略这一点,最好避免使用msg_peek)-您如何知道msg_peek或recv()所使用的套接字?同样,如果您是单线程的,那么您要么在第一次peek/recv尝试时阻塞,要么使用非阻塞模式,然后疯狂地旋转通过所有描述符,希望peek/recv返回一些东西。浪费的 所以,坚持1或移动到多线程模型。对于后者,最简单的方法是让监听线程循环调用accept,每次accept都会生成一个新的客户机描述符,它应该生成一个新的线程来处理连接。这些客户端连接处理线程可以简单地在recv()中阻塞。这样,操作系统本身就可以对线程进行监视和唤醒,以响应事件,您可以相信它会相当有效。虽然这个模型听起来很简单,但是您应该知道多线程编程还有很多其他的复杂之处——如果您还不熟悉它,那么您可能不想在了解套接字I/O的同时尝试了解它。 |
![]() |
2
3
此外,使用方法1,您可以阻止至少一个连接 是 准备就绪(在这种情况下没有开销,这在不那么繁忙的系统中并不少见)--对于其他方法,您需要进行“轮询”,即, 搅动 ,不断地,烧掉大量的CPU,没有任何好的用途(或者,如果在每次检查循环后你睡一段时间,那么你会延迟响应 尽管 系统一点也不忙——eep!-) 所以我才考虑 轮询 成为一个 反对的 -模式:经常使用,但仍然具有破坏性。有时你完全没有选择(这基本上告诉你你必须与设计很差的系统交互——唉,有时候在这个不完美的生活中你 做 不得不!-但是如果有合适的选择 做 尽管存在,但是进行轮询确实是一个非常糟糕的设计实践,应该避免。 |
![]() |
3
3
您可以简单地对3个场景进行一些效率模拟,其中:
方案A(0/500输入数据)
方案B(250/500输入数据)
**假设跳过没有缓冲区大小的套接字@no incoming data
|