二十九、python多线程、多进程、协程中涉及的知识点
1、GIL全局解释器锁
https://www.cnblogs.com/nuochengze/p/12664602.html
1、GIL是CPython解释器的特点, 在其它解释器中不存在
2、GIL本质是一把互斥锁,但它是解释器级别的锁
3、它的存在是因为CPython解释器内存管理不是线程安全的
内存管理,即垃圾回收机制,包括
引用计数
标记清除
分代回收
4、GIL的存在导致了用一个进程下的多个线程无法利用多核优势
5、针对不同的数据应该加不同的锁来保证安装
2、互斥锁、死锁与递归锁
https://www.cnblogs.com/nuochengze/p/12640152.html中1.4同步
3、信号量
-
-
在并发编程中信号量指的是
from threading import Semaphore, Thread import time import random sm = Semaphore(5) def task(name): sm.acquire() print("%s 正在执行" % name) time.sleep(random.randint(1, 5)) sm.release() if __name__ == "__main__": for i in range(20): t = Thread(target=task, args=('%s 号' % i,)) t.start()
4、Event
# 一些线程/进程等待另外一些线程/进程发送可以运行的信号, 才开始运行 from theading import Event e = Event() # 等待 e.wait() # 发送信号 e.set()
5、队列
-
先进先出
-
LifoQueue
后进先出
-
PriorityQueue
可以给放入队列中的数据设置优先级
""" 它的出现是为了保证计算机硬件的安全 降低了程序的运行效率,但是保证了计算机硬件安全 """ from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor import time pool = ThreadPoolExecutor(5) # 池子里面固定只有五个线程 """ 括号内可以传数字,不传的话默认会开设当前计算机CPU个数五倍的线程 池子造出来之后,里面会固定存在五个线程,这5个线程不会重复创建和销毁 """ """ 将任务提交给池子,就能使用 """ def task(n): print(n) return n * n """ 任务的提交方式: 同步:提交任务之后原地等待任务的返回结果,期间不做任何事情 异步:提交任务之后不等待任务的返回结果,继续往下执行 """ def task_call(n): print(">>>> %s" % n.result()) for i in range(20): pool.submit(task, i).add_done_callback(task_call) # submit异步提交 # submit其实会返回一个Future类的对象,该对象调用result就能获取到任务的结果 # 池子对象的方法 # pool.shutdown() # 关闭池子,等待池子中所有的任务运行结束,再继续往后执行代码 # 异步回调机制 # 给每一个异步提交的任务绑定一个方法,一旦任务有结果了会立即自动触发该方法
7、总结
多进程下面开设多线程
多线程下面再开设协程
从而使程序执行效率提升