async and awaitpython
what we have
thread -> the GIL
processes
concurrent.futures多线程
cpu limit
io multi cutting异步
async -> io and item can cut and solo item needs some time
https://www.youtube.com/watch?v=iLHRZ8VONsE
https://www.youtube.com/watch?v=tSLDcRkgTsYasync
a style of concurrent programe
do multiple things at once at python
multiple processesoop
import asyncio async def main(): print('hello...') await asyncio.sleep(3) print('...world ') asyncio.run(main()) # RuntimeError: asyncio.run() cannot be called from a running event loop, jupyter is already running an event loop await main() # 会阻塞
import asyncio import time async def say_after(delay, what): await asyncio.sleep(delay) print(what) async def main(): print(f"started at {time.strftime('%X')}") await say_after(2, 'hello') await say_after(2, 'world') print(f"finished at {time.strftime('%X')}") # asyncio.run(main()) await main() # 同步的
# task 异步 async def main(): task1 = asyncio.create_task(say_after(2, 'hello')) task2 = asyncio.create_task(say_after(2, 'hello')) print(f"started at {time.strftime('%X')}") await task1 await task2 print(f"finished at {time.strftime('%X')}") await main()
# running tasks concurrently, awaitable asyncio.gather() 异步,使用gather自动任务调度 # There are three main types of awaitable objects: coroutines, Tasks, and Futures. import asyncio async def factorial(name, number): f = 1 for i in range(2, number + 1): print(f"task {name}: compute factorial({i})") await asyncio.sleep(1) f *= i print(f"task {name}: factorial({number}) = {f}") async def main(): await asyncio.gather( factorial('A', 2), factorial('B', 3), factorial('C', 4) ) await main()
youtube 连接 :
笔记连接:https://osf.io/w8u26/线程
import time import asyncio def is_prime(x): return not any(x//i == x/i for i in range(x-1, 1, -1)) async def highest_prime_below(x): print('Highest prime below %d' % x) for y in range(x-1, 0, -1): if is_prime(y): print('→ Highest prime below %d is %d' % (x, y)) return y await asyncio.sleep(0.01) return None async def main(): t0 = time.time() await asyncio.wait( [ highest_prime_below(100000), highest_prime_below(10000), highest_prime_below(1000) ] ) t1 = time.time() print('Took %.2f ms' % (1000*(t1-t0))) loop = asyncio.get_event_loop() loop.run_until_complete(main())
import threading def countdown(): x = 10000000 while x > 0: x -= 1 def do_threading(): thread_1 = threading.Thread(target=countdown()) thread_2 = threading.Thread(target=countdown()) thread_1.start() thread_2.start() thread_1.join() thread_2.join() def run_implementation(): countdown() countdown() # 使用线程几乎没有什么用 # what is I/O bound
import multiprocessing def run_multiprocese(): process_1 = multiprocessing.Process(target=countdown) process_2 = multiprocessing.Process(target=countdown) process_1.start() process_2.start() process_1.join() process_2.join()
以上:https://hackernoon.com/concurrent-programming-in-python-is-not-what-you-think-it-is-b6439c3f3e6acode
Python标准库为咱们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,可是当项目达到必定的规模,
频繁建立/销毁进程或者线程是很是消耗资源的.
从Python3.2开始,标准库为咱们提供了concurrent.futures模块,它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类,
实现了对threading和multiprocessing的进一步抽象,对编写线程池/进程池提供了直接的支持。blog
from concurrent.futures import ProcessPoolExecutor import time def return_future_result(message): time.sleep(2) return message pool = ProcessPoolExecutor(max_workers=2) future1 = pool.submit(return_future_result, ("hello")) future2 = pool.submit(return_future_result, ("world")) print(future1.done()) time.sleep(3) print(future2.done()) print(future1.result()) print(future2.result())
from concurrent.futures import ThreadPoolExecutor import time def return_future_result(message): time.sleep(2) return message pool = ThreadPoolExecutor(max_workers=2) # 建立一个最大可容纳2个task的线程池 future1 = pool.submit(return_future_result, ("hello")) # 往线程池里面加入一个task future2 = pool.submit(return_future_result, ("world")) # 往线程池里面加入一个task print(future1.done()) # 判断task1是否结束 time.sleep(3) print(future2.done()) # 判断task2是否结束 print(future1.result()) # 查看task1返回的结果 print(future2.result()) # 查看task2返回的结果