Python 中的串行执行 并发执行 同步异步
2017-11-10 14:22
519 查看
程序的执行:
串行执行:
串行不以为效率一定低,当程序是纯计算的话,串行执行并没有效率问题.
但是如果遇到IO密集型程序串行使,效率极低.
所以需要进行 并发
并发执行(并行执行):
开启多进程或多线程并发执行,彼此互不干扰.
虽然python存在GIL锁,但在IO密集型时,多线程是有用的.
但是我们并不能无限制的开线程或者开进程,所以需要进程池或线程池.
进程池 线程池:
上边这个代码虽然调用任务是异步调用,但是查看结果时,还是串行查询,降低了效率,所以在异步调用时候要结合回调机制来使用.
将进程或线程控制在一定数量内(计算机可以承受的范围内).
但是如果任务规模 数量变大,池是有局限性,从而降低效率.
所以如何解决IO问题才是关键
执行任务的方式有同步和异步两种方式,即同步调用,异步调用.
同步调用:
提交完任务后,在原地等待任务执行完毕,拿到返回值,再执行下一行代码
异步调用 + 回调机制:
提交完任务(捆绑一个回调函数)后,不等待任务的执行,直接执行下一行代码,然后等到进程有结果直接触发回调函数的执行.
阻塞指的是进程的一种状态,在进程遇到IO时,会被操作系统夺走CPU的执行权限.
所以我们需要寻找以各种解决方案:
能检测单线程下的IO
遇到IO自动切换
python3.3之后,新增了asynico模块,可以帮组我们检测IO(只能是网络IO),实现应用程序的切换.
twisted 是一个网络框架,其中一个功能是发送异步请求,检测IO并自动切换.
tornado 框架,也能实现该功能.
串行执行:
import requests import time def get_page(url): print('GET: %s' %url) response=requests.get(url) print(url,len(response.text)) return response.text urls=[ 'https://www.baidu.com', 'https://www.python.org', 'https://www.openstack.org' ] #程序的执行是串行执行 start=time.time() for url in urls: res=get_page(url) #任务的调用方式是同步调用:提交一个任务,然后在原地等待,等待返回结果后再执行下一行代码 stop=time.time() print(stop-start) #2.664152145385742
串行不以为效率一定低,当程序是纯计算的话,串行执行并没有效率问题.
但是如果遇到IO密集型程序串行使,效率极低.
所以需要进行 并发
并发执行(并行执行):
from multiprocessing import Process from threading import Thread import requests import time def get_page(url): print('GET: %s' %url) response=requests.get(url) print(url,len(response.text)) return response.text urls=[ 'https://www.baidu.com', 'https://www.python.org', 'https://www.openstack.org' ] if __name__ == '__main__':#在python中开启多进程,需要在__main__下执行 #程序的执行是串行执行 start=time.time() p_l=[] for url in urls: p=Thread(target=get_page,args=(url,))#多线程 p_l.append(p) # p = Process(target=get_page, args=(url,)) #多进程 # p_l.append(p) p.start() for p in p_l: p.join() stop=time.time() print(stop-start) #2.664152145385742
开启多进程或多线程并发执行,彼此互不干扰.
虽然python存在GIL锁,但在IO密集型时,多线程是有用的.
但是我们并不能无限制的开线程或者开进程,所以需要进程池或线程池.
进程池 线程池:
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor from multiprocessing import Process from threading import Thread import requests import time def get_page(url): print('GET: %s' %url) response=requests.get(url) return len(response.text) urls=[ 'https://www.baidu.com', 'https://www.python.org', 'https://www.openstack.org' ] if __name__ == '__main__': p=ProcessPoolExecutor(4)#默认是你CPU核心数量 #程序的执行是串行执行 start=time.time() l=[] for url in urls: furture=p.submit(get_page,url) #任务的调用方式是异步调用:提交一个任务,不用等待,直接执行下一行代码 l.append(furture) p.shutdown(wait=True) for f in l: print(f.result()) stop=time.time() print(stop-start) #2.664152145385742
上边这个代码虽然调用任务是异步调用,但是查看结果时,还是串行查询,降低了效率,所以在异步调用时候要结合回调机制来使用.
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor from multiprocessing import Process from threading import Thread import requests import time,os,random def get_page(url): print('%s GET: %s' %(os.getpid(),url)) response=requests.get(url) # time.sleep(random.randint(1,3)) return len(response.text) def parse_page(res): res=res.result() print('%s parse res: %s' %(os.getpid(),res)) urls=[ 'https://www.baidu.com', 'https://www.python.org', 'https://www.openstack.org' ] if __name__ == '__main__': p=ProcessPoolExecutor(2) #程序的执行是串行执行 start=time.time() for url in urls: # p.submit(get_page,url).add_done_callback(parse_page) p.submit(get_page,url) p.shutdown(wait=True) stop=time.time() print(stop-start) #2.664152145385742 print('主',os.getpid())
将进程或线程控制在一定数量内(计算机可以承受的范围内).
但是如果任务规模 数量变大,池是有局限性,从而降低效率.
所以如何解决IO问题才是关键
执行任务的方式有同步和异步两种方式,即同步调用,异步调用.
同步调用:
提交完任务后,在原地等待任务执行完毕,拿到返回值,再执行下一行代码
异步调用 + 回调机制:
提交完任务(捆绑一个回调函数)后,不等待任务的执行,直接执行下一行代码,然后等到进程有结果直接触发回调函数的执行.
阻塞指的是进程的一种状态,在进程遇到IO时,会被操作系统夺走CPU的执行权限.
所以我们需要寻找以各种解决方案:
能检测单线程下的IO
遇到IO自动切换
python3.3之后,新增了asynico模块,可以帮组我们检测IO(只能是网络IO),实现应用程序的切换.
twisted 是一个网络框架,其中一个功能是发送异步请求,检测IO并自动切换.
tornado 框架,也能实现该功能.
相关文章推荐
- GCD的定义及使用详解(同步异步、并发串行、线程间通信、延时执行、只执行一次代码)
- 关于GCD中串行队列、并发队列和同步执行、异步执行的探讨
- GCD-同步,异步分别在串行队列,并发队列,主队列下的执行方式
- java并行,并发,串行,同步,异步,阻塞,非阻塞,同步阻塞,同步非阻塞,异步阻塞,异步非阻塞
- 多线程GCD+同步执行+异步执行+并行执行+串行执行+重复、分组、延迟、障碍方法
- GCD使用 串行并行队列 与 同步异步执行的各种组合 及要点分析
- python基础-协程gevent用法、协程同步异步、协程socket并发例子
- GCD串行并发同步异步基本概念
- GCD 术语 串行 vs. 并发 同步 vs. 异步
- 串行队列/并发队列&异步任务/同步任务代码演练
- iOS开发中的并发、串行队列,同步、异步任务
- GCD之同步函数、异步函数和串行队列、并发队列
- iOS 异步同步执行和并行串行队列的不解之缘
- GCD编程dispatch_sync(同步)和dispatch_async(异步)方式执行并发队列任务区别
- GCD--Serial(串行)和Concurrent(并发)、Synchronous(同步)和Asynchronous(异步)
- 帮你快速理解同步 ,异步,并发/并行,串行
- 开发要搞清楚什么是并发,并行,串行,同步,异步?
- Node.js的那些坑(四)——如何让异步并发方法同步顺序执行
- GCD 同步异步的串行和并发问题