为什么epoll接受新的fd并生成新的线程无法很好地扩展?

时间:2018-08-26 08:18:29

标签: epoll kqueue

我已经看到很多关于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;

1 个答案:

答案 0 :(得分:0)

AFAIU,epoll(7)本身不会产生新线程(另请参见pthreads(7) ...)。您需要一些其他调用(使用pthread_create使用的pthread_create(3)或基础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的库(查看libevlibeventGlibPoco,{ {3}},...或主要用于HTTP:Qt在服务器端,libonion在客户端)。另请参阅libcurl

0mqcallbackscontinuations相关的概念可能会有用,并可以改善您的思维。

Go及其Goroutines之类的语言可能会有所帮助。

  

它可能永远挂着....

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

大概花几周的时间来深入了解CPS概念应该是值得的。在了解了有关Linux编程的更多信息(例如,旧的Operating Systems书或更新的内容)之后,也应该理解大多数系统调用(在syscalls(2)中列出)。也许您不需要像epoll那样复杂的内容(因为仅使用poll就足够了。)