我已经看到很多关于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;
答案 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的库(查看libev,libevent,Glib,Poco,{ {3}},...或主要用于HTTP:Qt在服务器端,libonion在客户端)。另请参阅libcurl。
与0mq,callbacks,continuations相关的概念可能会有用,并可以改善您的思维。
Go及其Goroutines之类的语言可能会有所帮助。
它可能永远挂着....
如果您仔细设计程序(当然,使用诸如poll
或epoll_wait
之类的事件循环-有限的延迟少于一秒,并且可能更喜欢非阻塞IO),则不会发生这种情况)。
大概花几周的时间来深入了解CPS概念应该是值得的。在了解了有关Linux编程的更多信息(例如,旧的Operating Systems书或更新的内容)之后,也应该理解大多数系统调用(在syscalls(2)中列出)。也许您不需要像epoll
那样复杂的内容(因为仅使用poll
就足够了。)