同步
多线程异步提交任务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