同步
多线程异步提交任务Thread
线程池与进程池 ThreadPool
#IO密集型程序应该用多线程,所以此时我们使用线程池
import requests
from threading import current_thread
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
def parse_page(res):
res=res.result()
print('%s 解析 %s' %(current_thread().getName(),len(res)))
def get_page(url):
print('%s 下载 %s' %(current_thread().getName(),url))
response=requests.get(url)
if response.status_code == 200:
return response.text
if __name__ == '__main__':
urls=['https://www.baidu.com/','http://www.sina.com.cn/','https://www.python.org']
pool=ThreadPoolExecutor(50)
# pool=ProcessPoolExecutor(50)
for url in urls:
pool.submit(get_page,url).add_done_callback(parse_page)
pool.shutdown(wait=True)
高性能:
上面的所面临的可能同时出现的上千甚至上万次的客户端请求,“线程池”或“连接池”或许可以缓解部分压力,但是不能解决所有问题。总之,多线程模型可以方便高效的解决小规模的服务请求,但面对大规模的服务请求,多线程模型也会遇到瓶颈,可以用非阻塞接口来尝试解决这个问题。
上述无论哪种解决方案其实没有解决一个性能相关的问题:IO阻塞,无论是多进程还是多线程,在遇到IO阻塞时都会被操作系统强行剥夺走CPU的执行权限,程序的执行效率因此就降低了下来。
解决这一问题的关键在于,我们自己从应用程序级别检测IO阻塞然后切换到我们自己程序的其他任务执行,这样把我们程序的IO降到最低,我们的程序处于就绪态就会增多,以此来迷惑操作系统,操作系统便以为我们的程序是IO比较少的程序,从而会尽可能多的分配CPU给我们,这样也就达到了提升程序执行效率的目的
开启协程gevent
asyncio异步模块:
可以帮我们检测IO(只能是网络IO),实现应用程序级别的切换
twisted框架:
是一个网络框架,其中一个功能是发送异步请求,检测IO并自动切换
tornado
https://www.cnblogs.com/kermitjam/articles/10147258.html#_label2
https://www.cnblogs.com/kermitjam/articles/10516669.html#_label2