文章插图
常见并发服务器方案比较:
文章插图
三、一些常见问题
1、Linux能同时启动多少个线程?
对于 32-bit Linux , 一个进程的地址空间是 4G , 其中用户态能访问 3G 左右 , 而一个线程的默认栈 (stack) 大小是 8M , 心算可知 , 一个进程大约最多能同时启动 350 个线程左右 。
2、多线程能提高并发度吗?
如果指的是“并发连接数” , 不能 。
假如单纯采用 thread per connection 的模型 , 那么并发连接数大约350 , 这远远低于基于事件的单线程程序所能轻松达到的并发连接数(几千上万 , 甚至几万) 。所谓“基于事件” , 指的是用 IO multiplexing event loop 的编程模型 , 又称 Reactor 模式 。
3、多线程能提高吞吐量吗?
对于计算密集型服务 , 不能 。
如果要在一个8核的机器上压缩100个1G的文本文件 , 每个core的处理能力为200MB/s , 那么“每次起8个进程 , 一个进程压缩一个文件”与“只启动一个进程(8个线程并发压缩一个文件)” , 这两种方式总耗时相当 , 但是第二种方式能较快的拿到第一个压缩完的文件 。
4、多线程能提高响应时间吗?
可以 。参考问题3
5、多线程程序日志库要求
线程安全 , 即多个线程可以并发写日志 , 两个线程的日志消息不会出现交织 。
用一个全局的mutex保护IO
每个线程单独写一个日志文件
前者造成全部线程抢占一个锁(串行写入)
后者有可能让业务线程阻塞在写磁盘操作上 。(磁盘IO时间比较长)
解决办法:用一个logging线程负责收集日志消息 , 并写入日志文件 , 其他业务线程只管往这个“日志线程”发送日志消息(如通过BlockingQueue提供接口) , 这称为“异步日志” , 也是一个经典的生产者消费者模型 。
6、线程池大小的选择
如果池中执行任务时 , 密集计算所占时间比重为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忙个不停 。
7、线程分类
I/O线程(这里特指网络I/O)
计算线程
第三方库所用线程 , 如logging,又比如database
【linux下多线程与并发服务器设计方案及常见问题】
推荐阅读
- 如何解密 Linux 版本信息
- 深入聊聊Linux 五种IO模型
- kali linux之应用层Dos
- linux内核驱动第1讲:带你编写一个最简单的字符设备驱动
- Linux常规命令
- 整理 Linux下列出目录内容的命令
- linux系统中socket错误码:eintr和eagain的处理方法
- Linuxfx - 这套Linux操作系统看起来和Windows 10非常类似
- 外网主机A通过带内外网的Linux跳板机B直接访问内网机器C服务
- 带你阅读linux内核源码:下载源码、编译内核并运行一个最小系统