【问题标题】:Is network event based programming really better...? [closed]基于网络事件的编程真的更好吗...? [关闭]
【发布时间】:2011-03-21 07:40:53
【问题描述】:

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

【问题讨论】:

  • 您是否考虑过 select 允许在一个线程的多个 io 端口上阻塞,而简单的阻塞意味着每个 io 有一个线程。然后事件编程通常由底层 API(如 Windows 上的 io 端口)管理,这些 API 将为您运行比您编写的线程代码更好的线程代码。
  • 不清楚你在问什么。为了使这个问题变得更好,我建议扩展一些定义和解释。

标签: c select network-programming


【解决方案1】:

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

只有一堆线程每个处理整个连接生命周期比根据进程的某些部分何时必须阻塞、定时器何时关闭或谁知道什么来分配事件循环工作要简单得多其他事件。可悲的是,此时,越复杂的方法越快。

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

【讨论】:

    【解决方案2】:

    “更好”取决于您的需要。

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

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

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

    【讨论】:

      【解决方案3】:

      您可以在以下情况下使用阻塞同步 IO:

      • 您只有一个处于活动状态的套接字
      • 您的应用程序除了对套接字上的事件做出反应之外什么都不做
      • 您不打算扩展应用程序
      • 您不介意用户必须终止应用程序才能退出

      如果其中任何一个是错误的,那么您最好使用轮询循环。

      【讨论】:

        【解决方案4】:

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

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

        一般来说重点是使用选择还是线程?

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-26
          • 1970-01-01
          • 2010-09-06
          • 1970-01-01
          • 1970-01-01
          • 2014-06-27
          • 2012-04-27
          • 1970-01-01
          相关资源
          最近更新 更多