GIL、进/线程池、同/异步、阻/非阻塞

 2023-09-10 阅读 28 评论 0

摘要:1 GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在解释器身上的, 同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码2、GIL的优缺点: 优点: 保证Cpython解释器内存管理的线程安全 缺点: 同一进程内所有的线程同一时刻只

 

1 GIL:全局解释器锁
GIL本质就是一把互斥锁,是夹在解释器身上的,
同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码

2、GIL的优缺点:
优点:
保证Cpython解释器内存管理的线程安全

缺点:
同一进程内所有的线程同一时刻只能有一个执行,
也就说Cpython解释器的多线程无法实现并行
from threading import Thread,current_thread
import timedef 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 Threadimport timedef 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和非阻塞io? 

进程池与线程池:

为什么要用“池”?

   池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务

  池子内什么时候装进程:并发的任务属于计算密集型

hashmap并发问题?  池子内什么时候装线程:并发的任务属于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,randomdef task(x):print('%s 接客' %x)time.sleep(random.randint(2,5))return x**2if __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,randomdef task(x):print('%s 接客' %x)time.sleep(random.randint(1,3))return x**2if __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('')
同步调用

 

转载于:https://www.cnblogs.com/TF511/p/9954193.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/36469.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息