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。