欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python多线程多进程应用场景

程序员文章站 2022-07-12 11:11:42
...

IO密集型: 推荐使用多进程,多线程是鸡肋
CPU密集型: 推荐使用多进程或多线程

为什么Python多线程在IO密集型中是鸡肋?通过一段代码来测试

单线程执行从1亿递减到0

import datetime

def run(n):
    while n > 0:
        n -= 1
        
if __name__ == '__main__':
    start_time = datetime.datetime.now()
    n = 100000000
    run(n)
    end_time = datetime.datetime.now()
    print('用时:', end_time - start_time)
用时: 0:00:03.044011

启用两个线程t1, t2各运行5000万次

import threading
import datetime


def run(n):
    while n > 0:
        n -= 1

if __name__ == '__main__':
    start_time = datetime.datetime.now()
    n1 = 50000000
    n2 = 50000000
    threads = []
    t1 = threading.Thread(target=run, args=(n1,))
    threads.append(t1)
    t2 = threading.Thread(target=run, args=(n2,))
    threads.append(t2)
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    end_time = datetime.datetime.now()
    print('用时:', end_time - start_time)
用时: 0:00:03.384256

耗时不减反增。
那么是什么导致Python多线程不快反慢呢?
原因就是GIL(Global Interpreter Lock)全局解释器锁, 来源是python设计之初的考虑,为了数据安全所做的决定。在Cpython(python主流解释器)中,解释器解释执行python代码时,先要取得这把GIL锁,正是这把锁保证在解释器中同时只有一个线程在运行。在python多线程中,python解释器按照以下方式运行:

1.设置GIL
2.切换到一个线程执行
3.执行
4.把线程设置为睡眠状态
5.解锁GIL
6.重复以上步骤

因为涉及到线程切换(保存线程上下文)、锁处理机制(设置锁,释放锁),导致多线程不快反慢。
但是在IO密集型程序中,多线程依旧能大幅度提升程序执行效率。例如socket server、爬虫等,因为大多数时候程序实在等待socket返回数据,当线程遇到I/O操作时会释放GIL,结果就是某个线程在等待结果时其他线程可以继续执行。计算密集型(CPU密集型)每运行100次也会释放GIL。