基于网络事件的编程真的更好......?

时间:2011-03-21 07:40:54

标签: c select network-programming

使用基于事件的编程,你基本上只是循环和轮询,循环和轮询...为什么这只是阻止?如果您没有收到任何事件,为什么您更喜欢使用select()而不是仅仅阻止accept()?

4 个答案:

答案 0 :(得分:2)

通常这个问题就像基于事件的网络编程比基于线程的网络编程更好地利用资源一样。这个问题的一般答案在理论上是否定的,但实际上是肯定的。我记得一篇由Inktomi的创始人撰写的论文,后者的产品后来成为Apache Traffic Server(Traffic Server是一个基于事件的http代理)。基本上,结论是用户空间线程可以与基于事件的模型一样快。他们认为上下文切换总是会使操作系统级别的线程慢于事件模型。当时没有与基于事件的模型竞争的生产就绪用户空间线程模型。最后,他们指出在基于线程的模型上使用基于事件的模型的概念开销在大规模应用程序中是重要的。你已经注意到了这一点。

让每个处理整个连接生命周期的一堆线程比根据进程的某些部分必须阻塞,计时器何时关闭或者谁知道什么而进行事件循环调度工作要简单得多其他事件。可悲的是,在这个时候,更复杂的方法是更快。

注意:抱歉没有发布论文链接,但我现在似乎无法找到在线资源。我将尝试稍后使用链接编辑此帖子

答案 1 :(得分:1)

“更好”取决于你需要什么。

使用基于事件(select / poll / epoll / etc。)的IO,您可以在一个线程中侦听来自多个(数千个)套接字的事件。与使用每个套接字执行阻塞操作的一个线程相比,这可以极大地提高可伸缩性。

使用阻塞读/写/接受,您无法在一个线程中同时为多个客户端提供服务,每个连接至少需要使用一个线程/进程。这里的缺点是,它不能像基于事件的IO那样扩展。然而,编程模型变得更容易。

有时您需要调用仅提供阻止API的API(例如,查询后端数据库)。在这种情况下,如果你在基于事件的IO循环中执行此操作,则会阻止所有其他客户端,并且您基本上不得不求助于使用每个客户端的线程 - 如果在这种情况下需要可伸缩性,那么它很常见将事件循环与工作线程池结合起来,这可能会使编程模型更加困难。

答案 2 :(得分:0)

您可以在以下时间使用阻止同步IO:

  • 您只有一个套接字
  • 您的应用程序除了对套接字上的事件做出反应外没有做任何事情
  • 您不打算扩展应用程序
  • 您不介意用户必须终止该应用程序以退出

如果其中任何一个都是假的,那么你最好使用轮询循环。

答案 3 :(得分:0)

让程序阻止接受并不是一个好主意。这意味着在您的应用程序收到一些数据之前,不能执行任何其他操作。

即使您的网络要求非常简单,并且您不需要发送或接收阻塞套接字等待的其他数据,您甚至无法更新GUI(如果有)或接收输入来自用户。

一般来说,重点是使用select还是thread?

线程很难调试,并且可能会产生有关并发操作的问题。所以,除非你明确需要线程,否则我建议使用select。