GIL、进/线程池、同/异步、阻/非阻塞
2024-09-25 22:07:51
1 GIL:全局解释器锁
GIL本质就是一把互斥锁,是夹在解释器身上的,
同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码 2、GIL的优缺点:
优点:
保证Cpython解释器内存管理的线程安全 缺点:
同一进程内所有的线程同一时刻只能有一个执行,
也就说Cpython解释器的多线程无法实现并行
from threading import Thread,current_thread
import time def task():
print('%s is running' %current_thread().name)
time.sleep(3)
print('%s is done' %current_thread().name) if __name__ == '__main__':
t1=Thread(target=task)
t2=Thread(target=task)
t3=Thread(target=task)
t1.start()
t2.start()
t3.start()
验证
一、 计算密集型应该使用多进程:
#frommultiprocessingimportProcess#fromthreadingimportThread##importtime##importos##print(os.cpu_count())##deftask1():#res=0#foriinrange(1,100000000):#res+=i##deftask2():#res=0#foriinrange(1,100000000):#res+=i##deftask3():#res=0#foriinrange(1,100000000):#res+=i##deftask4():#res=0#foriinrange(1,100000000):#res+=i##if__name__=='__main__':##p1=Process(target=task1)##p2=Process(target=task2)##p3=Process(target=task3)##p4=Process(target=task4)##p1=Thread(target=task1)#p2=Thread(target=task2)#p3=Thread(target=task3)#p4=Thread(target=task4)#start_time=time.time()#p1.start()#p2.start()#p3.start()#p4.start()#p1.join()#p2.join()#p3.join()#p4.join()#stop_time=time.time()#print(stop_time-start_time)
多进程
二、IO密集型应该使用多线程:
from multiprocessing import Process
from threading import Thread import time def task1():
time.sleep(3) def task2():
time.sleep(3) def task3():
time.sleep(3) def task4():
time.sleep(3) if __name__ == '__main__':
# p1=Process(target=task1)
# p2=Process(target=task2)
# p3=Process(target=task3)
# p4=Process(target=task4) # p1=Thread(target=task1)
# p2=Thread(target=task2)
# p3=Thread(target=task3)
# p4=Thread(target=task4)
# start_time=time.time()
# p1.start()
# p2.start()
# p3.start()
# p4.start()
# p1.join()
# p2.join()
# p3.join()
# p4.join()
# stop_time=time.time()
# print(stop_time - start_time) #3.138049364089966 p_l=[]
start_time=time.time() for i in range(500):
p=Thread(target=task1)
p_l.append(p)
p.start() for p in p_l:
p.join() print(time.time() - start_time)
多线程
进程池与线程池:
为什么要用“池”?
池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务
池子内什么时候装进程:并发的任务属于计算密集型
池子内什么时候装线程:并发的任务属于IO密集型
# from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
# import time,os,random
#
# def task(x):
# print('%s 接客' %os.getpid())
# time.sleep(random.randint(2,5))
# return x**2
#
# if __name__ == '__main__':
# p=ProcessPoolExecutor() # 默认开启的进程数是cpu的核数
#
# # alex,武佩奇,杨里,吴晨芋,张三
#
# for i in range(20):
# p.submit(task,i) from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import time,os,random def task(x):
print('%s 接客' %x)
time.sleep(random.randint(2,5))
return x**2 if __name__ == '__main__':
p=ThreadPoolExecutor(4) # 默认开启的线程数是cpu的核数*5 # alex,武佩奇,杨里,吴晨芋,张三 for i in range(20):
p.submit(task,i)
代码演示
阻塞与非阻塞、同步与异步:
1、阻塞与非阻塞指的是程序的两种运行状态
阻塞:遇到IO就发生阻塞,程序一旦遇到阻塞操作就会停在原地,并且立刻释放CPU资源
非阻塞(就绪态或运行态):没有遇到IO操作,或者通过某种手段让程序即便是遇到IO操作也不会停在原地,执行其他操作,力求尽可能多的占有CPU
2、同步与异步指的是提交任务的两种方式:
同步调用:提交完任务后,就在原地等待,直到任务运行完毕后,拿到任务的返回值,才继续执行下一行代码
异步调用:提交完任务后,不在原地等待,直接执行下一行代码,结果?
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import time,os,random def task(x):
print('%s 接客' %x)
time.sleep(random.randint(1,3))
return x**2 if __name__ == '__main__':
# 异步调用
# p=ThreadPoolExecutor(4) # 默认开启的线程数是cpu的核数*5
#
# # alex,武佩奇,杨里,吴晨芋,张三
#
# obj_l=[]
# for i in range(10):
# obj=p.submit(task,i)
# obj_l.append(obj)
#
# # p.close()
# # p.join()
# p.shutdown(wait=True)
#
# print(obj_l[3].result())
# print('主')
异步调用
# 同步调用
p=ThreadPoolExecutor(4) # 默认开启的线程数是cpu的核数*5 # alex,武佩奇,杨里,吴晨芋,张三 for i in range(10):
res=p.submit(task,i).result() print('主')
同步调用
最新文章
- 【签名之坑】Decmail.GetBits()
- Tcl
- 012 VS2013常用快捷键
- C# 操作mongodb子文档
- JSoup笔记
- Android性能优化之布局优化
- Fitnesse启动参数与配置
- python对web服务器做压力测试并做出图形直观显示
- HDU 1231 最大连续子序列:水dp
- 拨开字符编码的迷雾--MySQL数据库字符编码
- ES6的变量解构赋值
- 解决IE8下opacity属性失效问题
- Ubuntu Server 18.04 修改网路配置
- java学习之—合并两个数组并排序
- Docker Kubernetes 高可用架构设计
- SpringMVC Hello World
- 基于external version进行乐观锁并发控制
- Sharding-jdbc(一)分库分表理解
- Spark笔记(一):错误总结
- jcseg-1.8.7版本发布 - 多配置适应+完整开发帮助文档