【问题标题】:why epoll accepted new fd and spawn new thread doesn't scale well?为什么 epoll 接受了新的 fd 并产生了新的线程不能很好地扩展?
【发布时间】:2019-02-01 02:44:53
【问题描述】:

我看到很多关于 epoll 接受新 fd 并生成新线程以在它自己的线程上读写的争论不能很好地扩展?但它如何不能很好地扩展?如果每个连接都有繁重的处理,例如:-

  • 做数据库事务
  • 做繁重的算法工作
  • 等待其他事情完成。

如果我的目的肯定只是想在程序内部做事(不再花哨的路由到其他连接来做事),并且不要为读/写 io 生成新线程。它可能会因为一个函数在等待某事而永远挂起,对吗?如果是这种情况,如果不产生新线程,epoll 的扩展性如何?

epoll_wait(...);

// available to read now
recv(....);

// From here if i don't spawn thread, the program will be hanging. What should I do?
processing algorithm work.....// At least 3 secs to do the job.


continue;

【问题讨论】:

  • 没有任何minimal reproducible example,您的问题看起来太宽泛了。
  • 我不确定你是否需要(起初)epoll(7)。但是您肯定需要了解我的回答中提到的概念。

标签: epoll kqueue


【解决方案1】:

AFAIU,epoll(7) 本身不会产生新线程(另请参阅pthreads(7)...)。您需要一些其他调用(使用pthread_create(3)pthread_create 使用的底层clone(2) 系统调用...)来创建线程。

阅读更多关于C10K problem(今天应该称为C100K)和一些pthread tutorial的信息。但看起来您的程序可能是计算密集型的,而不是 IO 密集型的。所以瓶颈可能是计算机能力(那么你无法通过单个计算机节点上的多线程获得可扩展性;你需要distributed computing

线程是相当重的资源。所以你想要一些thread pool 并且只有几十个活动(即可运行)线程。见this

还要注意其他多路复用系统调用(例如 poll(2))、非阻塞 IO(fcntl(2)O_NONBLOCK)、异步 IO(请参阅 aio(7))。

我建议使用一些现有基于event-loop 的库(查看libevlibeventGlibPocoQt,...或主要用于 HTTP :libonion 在服务器端,libcurl 在客户端)。还请查看0mq

callbackscontinuationsCPS 相关的概念可能很有用,可以提高您的思维。

Go 及其 Goroutine 等语言可能会有所帮助。

它可能永远挂着......

如果您仔细设计程序,则不会发生这种情况(当然,事件循环使用 pollepoll_wait 之类的东西 - 延迟小于一秒,并且可能更喜欢非阻塞 IO)。

或许,花几周时间了解更多关于Operating Systems 概念的知识应该是值得的。在阅读有关 Linux 编程的更多信息(例如旧的 ALP 书籍或更新的书籍)之后,还应该了解大多数系统调用(在 syscalls(2) 中列出)应该是可取的。也许您不需要像epoll 这样复杂的东西(因为只使用poll 可能就足够了)。

【讨论】:

  • 就我而言,我只能使用线程池来处理问题,对吗?我不能只是等待完成的事情并再次返回 epoll
  • 我觉得你很困惑,需要几个星期的阅读。我不确定您是否需要 epoll(但您肯定需要一些事件循环,可能基于 poll 并使用非阻塞 IO)
猜你喜欢
  • 2012-04-06
  • 2018-06-21
  • 2012-05-02
  • 1970-01-01
  • 2017-06-16
  • 2014-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多