async & await

async and awaitpython

  • 解決的問題
    can do more things at once
    can't make db / io network faster
  • CPU VS I/O
  • synchronous vs asynchronous
  • parallelism and concurrency

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

  • the os does all the multi-tasking work
  • only option for multi-core concurrency
    multiple threads
  • the os does all the multi-tasking work
  • in cpython, the GIL prevents multi-core concerrency
    asynchronous programming
  • no os intervention
  • one process, one thread
    synchronous chess exhibition -> 一我的和多我的下棋,走動

python 3.7.3 documentation

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())

threading

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

time

multiprocessing

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

threadpool

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返回的結果
相關文章
相關標籤/搜索