# IO

### 计算密集型任务 & IO密集型任务

#### CPU核心 & 线程

核心是可以分别独立运行程序指令的计算单元。 线程是操作系统能够进行运算调度的最小单位。

原则：活跃线程数为 CPU(核)数时最佳。过少的活跃线程导致 CPU 无法被充分利用，过多的活跃线程导致过大的线程上下文切换开销。

#### 计算密集型&#x20;

计算密集型，顾名思义就是应用需要非常多的CPU计算资源，在多核CPU时代，我们要让每一个CPU核心都参与计算，将CPU的性能充分利用起来，这样才算是没有浪费服务器配置，如果在非常好的服务器配置上还运行着单线程程序那将是多么重大的浪费。对于计算密集型的应用，完全是靠CPU的核数来工作，所以为了让它的优势完全发挥出来，避免过多的线程上下文切换，比较理想方案是： ***线程数 = CPU核数+1*** 。对于JAVA编程来说，也可以设置成CPU核数\*2，这还是要看`JDK`的使用版本，以及CPU配置(服务器的CPU有超线程)。对于`JDK1.8`来说，里面增加了一个并行计算，计算密集型的较理想线程数 = CPU内核线程数\*2。

#### IO密集型&#x20;

对于IO密集型的应用，就很好理解了，我们现在做的开发大部分都是WEB应用，涉及到大量的网络传输，不仅如此，与数据库，与缓存间的交互也涉及到IO，一旦发生IO，线程就会处于等待状态，当IO结束，数据准备好后，线程才会继续执行。因此从这里可以发现，对于IO密集型的应用，我们可以多设置一些线程池中线程的数量，这样就能让在等待的这段时间内，线程可以去做其它事，提高并发处理效率。 那么这个线程池的数据量是不是可以随便设置呢？当然不是的，请一定要记得，线程上下文切换是有代价的。目前总结了一套公式，对于IO密集型应用： ***线程数 = CPU核心数/(1-阻塞系数)*** 。这个阻塞系数一般为0.8\~0.9之间，也可以取0.8或者0.9。套用公式，对于双核CPU来说，它比较理想的线程数就是20，当然这都不是绝对的，需要根据实际情况以及实际业务来调整。

计算密集型程序适合C语言多线程，I/O密集型适合脚本语言开发的多线程。Python 中的多线程适合 IO 密集型任务，而不适合计算密集型任务。对于计算密集型任务，Python 下比较好的方式是使用多进程，这样可以非常有效的使用 CPU 资源。
