多线程{CPU密集型 && I/O密集型}

1.任务类型举例:

        1.1: CPU密集型:

                例如,一般我们系统的静态资源,比如js,css等,会存在一个版本号,如 main.js?v0,每当用户访问这个资源的时候,会发送一个比对请求到服务端,比对本地静态文件版本和服务端的文件版本是否一致,不一致则更新.这种任务一般不占用大量IO,所以后台服务器可以快速处理,压力落在CPU上.

        1.2: I/O密集型:

                当常有大数据量的查询和批量插入操作,此时的压力主要在I/O上.

2.线程数与任务类型的关系:

        2.1:与CPU密集型的关系:

                一般情况下,CPU核心数 == 最大同时执行线程数.在这种情况下(设CPU核心数为n),大量客户端会发送请求到服务器,但是服务器最多只能同时执行n个线程.

                设线程池工作队列长度为m,且m>>n,则此时会导致CPU频繁切换线程来执行(如果CPU使用的是FCFS,则不会频繁切换,如使用的是其他CPU调度算法,如时间片轮转法,最短时间优先,则可能会导致频繁的线程切换).

                所以这种情况下,无需设置过大的线程池工作队列,(工作队列长度 = CPU核心数 || CPU核心数+1) 即可.

            而在 Python 中,线程默认加入了 GIL 锁(Global Interpreter Lock), 线程执行前,必须先获得 GIL 锁,每执行 100 条字节码,解释器自动释放 GIL 锁,让别的线程执行。因此,多线程不是并行执行的,而是交替执行,在多 CPU 上也只能使用一个 CPU,所以多线程不能在 CPU 密集型任务下加速。

        2.2:与I/O密集型的关系:

                1个线程对应1个方法栈,线程的生命周期与方法栈相同.

比如某个线程的方法栈对应的入站顺序为:controller()->service()->DAO(),由于DAO长时间的I/O操作,导致该线程一直处于工作队列,但它又不占用CPU,则此时有1个CPU是处于空闲状态的.

                所以,这种情况下,应该加大线程池工作队列的长度(如果CPU调度算法使用的是FCFS,则无法切换),尽量不让CPU空闲下来,提高CPU利用率。另外,多线程中,可以一个线程使用 写入硬盘 资源,另一个使用 接收数据 资源,等其他 I/O资源,实现加速。

参考:

https://www.cnblogs.com/hellojesson/p/5953036.html

猜你喜欢

转载自blog.csdn.net/weixin_40017590/article/details/80601065
今日推荐