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返回的結果