并发服务器模式的几个问题

Linux能同时启动多少个线程?

对于 32-bit Linux,一个进程的地址空间是 4G,其中用户态能访问3G左右,而一个线程的默认栈 (stack)大小是8M,心算可知,一个进程大约最多能同时启动350个线程左右。

多线程能提高并发度吗?

如果指的是“并发连接数”,不能。假如单纯采用 thread per connection
的模型,那么并发连接数大约350,这远远低于基于事件的单线程程序所能轻松达到的并发连接数(几千上万,甚至几万)。所谓“基于事件”,指的是用IO multiplexing event loop的编程模型,又称Reactor模式。

多线程能提高吞吐量吗?

对于计算密集型服务,不能。如果要在一个8核的机器上压缩100个1G的文本文件,每个core的处理能力为200MB/s,那么“每次起8个进程,一个进程压缩一个文件”与“只启动一个进程(8个线程并发压缩一个文件)”,这两种方式总耗时相当,但是第二种方式能较快的拿到第一个压缩完的文件。

多线程能提高响应时间吗?

可以。参考问题3

多线程程序日志库要求

线程安全,即多个线程可以并发写日志,两个线程的日志消息不会出现交织。

  1. 用一个全局的mutex保护IO
  2. 每个线程单独写一个日志文件
    前者造成全部线程抢占一个锁(串行写入) 后者有可能让业务线程阻塞在写磁盘操作上。(磁盘IO时间比较长)

解决办法:用一个logging线程负责收集日志消息,并写入日志文件,其他业务线程只管往这个“日志线程”发送日志消息,这称为“异步日志”,也是一个经典的生产者消费者模型。

线程池大小的选择

如果池中执行任务时,密集计算所占时间比重为P(0<P<=1),而系统一共有C个CPU,为了让C个CPU跑满而不过载,线程池大小的经验公式T=C/P,即T*P=C(让CPU刚好跑满 )
假设C=8,P=1.0,线程池的任务完全密集计算,只要8个活动线程就能让CPU饱和
假设C=8,P=0.5,线程池的任务有一半是计算,一半是IO,那么T=16,也就是16个“50%繁忙的线程”能让8个CPU忙个不停。

线程分类

1.I/O线程(这里特指网络I/O)2.计算线程 3.第三方库所用线程,如logging,又比如database