多线程数量思考
上下文切换
即使是单核CPU也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制(因为通常一个任务不光cpu上要花时间,io上也要花时间,一个进程在等 io的时候,cpu 是闲置的,另一个进程正好可以利用cpu把cpu该做的事做完。多几个进程一起跑,可以把 io 和 cpu 都跑满了,可以充分利用CPU空闲)。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程时同时执行的,时间片一般是几十毫秒(ms)。
CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再次加载这个任务的状态,从任务保存到再加载的过程就是一次上下文切换。
这就像我们同时读两本书,当我们在读一本英文的技术书籍时,发现某个单词不认识, 于是便打开中英文词典,但是在放下英文书籍之前,大脑必须先记住这本书读到了多少页的第多少行,等查完单词之后,能够继续读这本书。这样的切换是会影响读书效率的,同样上下文切换也会影响多线程的执行速度。
问题:N核CPU执行N个线程,是否不存在上下文切换?
结论:
使用多线程往往可以获得更大的吞吐率和更短的响应时间,但是,使用多线程不一定就比单线程程序跑的快,这取决于我们程序设计者的能力以及应用场景的不同。
考虑到内存限制、资源争夺(除了CPU执行上下文切换的消耗以外,线程的执行还将有其他一些资源的消耗,比如:内存同步的开销(线程需要一些内存在维持线程本地栈,每个线程都有本地独立的栈用以存储线程专用数据),上下文切换的开销,线程创建和消亡的开销,以及调度的开销(占用操作系统的一些资源来管理和协调线程))、CPU密集型应用还是IO密集型应用、线程上下文切换等情况,线程数并不是越多越好,过多的线程数反而会影响处理效率,一般黄金眼项目中计算PV和UV时,4核cpu的情况下1个进程理论上开8个线程,实际上开20-30个线程最好,不可能到100个线程。