概念:
多进程: 是以cpu为最小单位的执行程序,利用cpu多核能力,真正的并发执行, 占用资源比线程较多
多线程: 是运行在一个进程里的多个并发程序,是执行程序的最小单位, 利用了cpu和io可以同时执行的原理
协程: 实在一个线程中 利用cpu和io并行执行的原理,可以实现函数异步执行
怎样根据任务选择对应的技术?
待执行任务是cpu密集型 -> 选择多进程
待执行任务是io密集型 -> 考虑 是否需要超多任务量?
有现成些协程库支持?
使用多线程 否 <------ 协程实现复杂度是否可以接受? -----> 是 使用多协程
一般情况下使用线程可以解决大部分问题
协程的缺点是支持的库有限制,很多程序是不支持协程的, 代码实现比较复杂(只能实现有现成库支持的场景)
协程是在单线程内实现并发
核心原理: 用一个超级循环(其实就是while True)
配合io多路复用原理(io时cpu可以去干其他事情)
注意:在异步io编程中,依赖的库必须支持异步io特性
执行await的时候不能阻塞,不然单线程就没办法并发执行了
import asyncio
#获取事件循环
loop = asyncio.get_event_loop()
# 定义协程
asyncio def craw(url):
await get_url(url):
pass
# 创建task列表
tasks = [loop.create_task(craw(url) for url in urls]
# 执行爬虫事件列表
loop.run_until_complete(asyncio.wait(tasks))
协程可以使用信号量(semaphore) 控制爬虫的并发量,防止把网站爬坏
lock:
Lock对资源加锁,防止冲突访问
多线程多进程都有lock
总结:
-
多进程主要适用于cpu密集型的任务,多进程的开启是有上限的,根据cpu的决定开启上限
-
多线程由于GIL的存在同一时刻只有一个线程能够使用cpu,所以不适用于cpu密集型任务,不过可以使用IO密集型任务,多线程还是遵循io并发任务原则
-
异步io单线程利用cpu和io同步执行的原理,实现了函数异步执行
-
线程占用内存资源,并且线程切换的开销比较大,这些开销协程是没有的