异步 I/O 与线程池 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mason961125
V2EX    C

异步 I/O 与线程池

  •  
  •   mason961125 2016-08-20 23:47:15 +08:00 3266 次点击
    这是一个创建于 3344 天前的主题,其中的信息可能已经有所发展或是发生改变。

    貌似 nginx 早期一直使用的是多进程+异步 I/O 的模式,后来(据说,个人未求证,只是在某技术博客里看到)使用了线程池技术。

    但是,既然已经使用了异步 I/O ,线程池还有存在的必要吗?如果有,为什么?

    18 条回复    2016-08-22 08:52:21 +08:00
    denghongcai
        1
    denghongcai  
       2016-08-20 23:54:58 +08:00
    http://www.infoq.com/cn/articles/thread-pools-boost-performance-9x

    性能提升也是在特定场景下,具体情况具体分析
    fcicq
        2
    fcicq  
       2016-08-20 23:59:08 +08:00   1
    FreeBSD 不需要楼上所说的这个优化, 这个优化仅限 Linux 才有意义.
    wevsty
        3
    wevsty  
       2016-08-21 00:55:40 +08:00
    异步 I/O 最大只能使用单核心,对于多核心的处理器来说并不能达到最大处理能力。多进程或者多线程可以使用多个处理器核心。既然要使用多进程或者多线程,那么进程池或者线程池就是有必要的。
    czz19891012
        4
    czz19891012  
       2016-08-21 01:18:33 +08:00   2
    你这个是 concurrency 的问题吧. 其实多线程, 你说的异步 IO(其实是 IO 多路复用) 都是实现 concurrency 的两个方式
    比如像 redis 单线程基于 epoll 这种模型, node.js 这种模型都可以归结为 Event-base Concurrency, 那么这种模型和 multi-thread 对比有什么区别呢?

    从这个角度来看 multi-thread 是 kernel 来决定下一个要调度处理的 thread 是哪一个, 线程数据多了无论是资源还是调度都会有点问题

    event-base 是所有的事件都放在一个 thread 上, 然后由这个 thread 来决定下一个要执行的 event 是谁?

    因为 multi-thread 会考虑到每一个 thread 的优先级等等, 而且如果 thread 数目过多那么肯定会影响到具体的调度. 对比 event-base, 切换线程需要切换上下文, 因此肯定会有性能的损耗. 而在 event-base 里面, 所有的 event 的优先级都是一样的, 然后在处理 event 的 handler 里面决定先处理哪一个 event. 但是同样有一个问题就是如果这个 event-base 里面 event 比较多, 那么性能肯定也会下来.而且 event-base 的另一个缺点就是没办法使用到多线程

    所以一般都是采用多线程 + 事件的方式来写网络编程了现在.
    nginx 是, lighttpd 是, 我们开源的 pika( https://github.com/Qihoo360/pika )也是

    我们还实现了这种模型的库 https://github.com/Qihoo360/pink
    UnisandK
        5
    UnisandK  
       2016-08-21 01:33:39 +08:00
    不知道你要的是不是这个,转

    不要让内核做所有繁重的工作。将数据包处理,内存管理和线程调度等从内核中移出来,放到应用程序里,使其处理得更加高效。让 Linux 内核处理控制面,应用程序处理数据面。

    这样,系统在处理上千万的并发连接时, 200 个时钟周期用于数据包处理, 1400 个时钟周期用于程序逻辑。由于内存访问要使用 300 个时钟周期,使用减少代码和减少 cache 丢失的方法进行设计也是关键所在。

    内核中两个基本问题:
    1 ) 连接数 = 线程数 / 进程数。一个数据包进来,内核要遍历所有 10,000 个进程找到处理这个数据包的进程。
    2 ) 连接数 = select 数 / poll 数。同样的可扩展问题,每一个数据包都要遍历 sockets 列表。

    解决方法:为内核打上补丁,使其查找时间为常数。
    1 ) 现在无论线程数量多少,线程的切换时间是常数。
    2 ) 使用 epoll()/IOCompeltionPort 可扩展的系统调用能够在常数时间查找 socket 。
    线程调度仍不能够扩展,所以服务器使用 epoll 的异步编程模型,在 Node 和 Nginx 中都体现了。即使一台较慢的服务器,增加连接数时性能不会急剧下降。
    FrankHB
        6
    FrankHB  
       2016-08-21 04:14:54 +08:00
    @UnisandK 转也留个出处吧……虽然不难找。

    倒是巧合,刚在看 dpdk 的代码。

    不过这个说到底也是根据场景优化的了。而且大概年代的关系看样子挖掘的还不够,比如提到 cache 也没管 cache allocation 什么的新型黑科技……
    UnisandK
        7
    UnisandK  
       2016-08-21 09:58:46 +08:00
    @FrankHB 直接记在笔记软件里的,偷懒没再去专门找出处
    hitmanx
        8
    hitmanx  
       2016-08-21 12:55:47 +08:00 via iPhone
    你是想问异步 io vs 多线程,还是随用随创建线程 vs 线程池?
    kingoldlucky
        9
    kingoldlucky  
       2016-08-21 13:19:36 +08:00
    异步也需要多线程的支持的 所以需要线程池
    SlipStupig
        10
    SlipStupig  
       2016-08-21 16:19:23 +08:00
    @kingoldlucky JS 表示为什么同样是异步,我却没有多线程
    tinyproxy
        11
    tinyproxy  
       2016-08-21 16:45:12 +08:00
    @SlipStupig 我想你说的应该是 nodejs 吧, nodejs 的事件驱动用的是 libuv ,贴个链接好了 https://github.com/libuv/libuv/blob/b12624c13693c4d29ca84b3556eadc9e9c0936a4/src/unix/fsevents.c#L46

    文件异步 IO 一般两种实现方式,最简单的就是线程池,另一种方式请移步 stackoverflow ,我只记得跟系统有关,具体怎么做的忘了。
    qiukun
        12
    qiukun  
       2016-08-21 17:02:32 +08:00
    @fcicq 结果这楼没人理你(
    kingoldlucky
        13
    kingoldlucky  
       2016-08-21 17:18:20 +08:00
    @SlipStupig 只不过把多线程这块交给浏览器去做了而已
    owt5008137
        14
    owt5008137  
       2016-08-21 17:31:27 +08:00 via Android
    @denghongcai 贴的那篇文章已经解释得相当好了。其实这里用线程池也就是扮演一个简单通用的减少阻塞的方案。否则的话针对特定系统,用特定的方法也是可以的。最不济多开几个进程嘛。不过进程数太多会有一定的内存浪费和 CPU 浪费就是了。
    fcicq
        15
    fcicq  
       2016-08-21 17:37:51 +08:00
    @qiukun 没关系. Solaris 系理论也不需要. 只会用 Linux 的人太多.
    pubby
        16
    pubby  
       2016-08-21 18:42:38 +08:00
    @fcicq FreeBSD 还是不错的, zfs 上开 jail 也各种方便。就是基金会有点穷,今年已经去捐了两次了 -_-
    fcicq
        17
    fcicq  
       2016-08-21 19:20:53 +08:00
    @pubby 但是 jail 和 zones 差太远了, 而且 ZFS 的主场当然是 Solaris ... 但是 joyent 被三星收购之后情况也看不清了.
    henglinli
        18
    henglinli  
       2016-08-22 08:52:21 +08:00 via iPhone
    1024cores.net 有讲怎么并行并发等设计的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     882 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 21:22 PVG 05:22 LAX 14:22 JFK 17:22
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86