下面是三个线程并发执行将一个变量累加.
运行环境:
mac 8核16G
python 3.7.7
import time
import threading
tag = 0
def task1():
print('任务1开始')
global tag
for i in range(1000000):
tag +=1
# print(tag)
time.sleep(1)
print('任务1结束')
def task2():
print('任务2开始')
global tag
for i in range(1000000):
tag += 1
# print(tag)
time.sleep(1)
print('任务2结束')
def task3():
print('任务2开始')
global tag
for i in range(1000000):
tag += 1
# print(tag)
time.sleep(1)
print('任务2结束')
if __name__ == '__main__':
thread1 = threading.Thread(target=task1, args='')
thread2 = threading.Thread(target=task2, args='')
thread3 = threading.Thread(target=task3, args='')
# thread2.setDaemon(True)
start = time.time()
thread1.start()
thread2.start()
thread3.start()
thread1.join()
thread2.join()
thread3.join()
print('主程序结束')
print(time.time() - start)
-
执行结果 :
任务1开始
任务2开始
任务2开始
任务2结束
任务2结束
任务1结束
主程序结束
1.2913100719451904
可以看到, 用时1秒多, CPU占用极低
-
打开print注释, 再次执行:
-
用时多了很多, 而且CPU利用超过了100%, 说明print 函数在大量循环的情况下会很耗时间, 而且多个线程中的print使得python占用多核CPU , 并不只是单核运行.
去掉time.sleep(1) 又会是不同的效果.
总结:
- GIL 使得python单核运行,几乎是一个单线程程序
- 纯计算的程序, 多线程还不如单线程
- 有网络请求、延时之类的代码, 多线程会体现出来优势
- IO 才是大瓶颈, 比如频繁print也会消耗大量时间