async & await

async and await

  • 解决的问题
    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=tSLDcRkgTsY

a style of concurrent programe
do multiple things at once at python
multiple processes

  • 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-b6439c3f3e6a

threadpool

Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,
频繁创建/销毁进程或者线程是非常消耗资源的.
从Python3.2开始,标准库为我们提供了concurrent.futures模块,它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类,
实现了对threading和multiprocessing的进一步抽象,对编写线程池/进程池提供了直接的支持。

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返回的结果
原文地址:https://www.cnblogs.com/bruspawn/p/10821150.html