基于网络事件的编程真的更好吗......? [已关闭]

问题描述 投票:0回答:4

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

c network-programming posix-select
4个回答
2
投票

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

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

注意:很抱歉没有发布该论文的链接,但我现在似乎找不到在线资源。稍后我会尝试用链接编辑这篇文章


1
投票

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

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

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

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


0
投票

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

  • 您只有一个活动套接字
  • 您的应用程序除了对套接字上的事件做出反应之外不执行任何操作
  • 您不打算延长申请时间
  • 您不介意用户必须杀死应用程序才能退出

如果其中任何一个是错误的,那么使用轮询循环可能会更好。


0
投票

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

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

一般要点是用select还是线程?

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

© www.soinside.com 2019 - 2024. All rights reserved.