python 非同步的幾種方式

vx_guanchaoguo0發表於2024-09-12
import asyncio
import random
import threading
from concurrent.futures import ThreadPoolExecutor
import time

def blocking_task(x):
    time.sleep(2)
    thread_name()
    print(f'arg:{x}\n')
    return x * 2

async def unblocking_task(x):
    thread_name()
    await asyncio.sleep(4)
    return x * 2

async def task_run_in_one_executor():
    print(f'task_run_in_one_executor')
    with ThreadPoolExecutor() as executor:
        futures = []
        loop = asyncio.get_event_loop()
        for x in range(10):
            futures.append(loop.run_in_executor(executor, blocking_task, x))
        print(await asyncio.gather(*futures))

def blacking_task():
    time.sleep(5)
    thread_name()
    return "after 5s"


async def return_future():
    current_loop = asyncio.get_event_loop()
    future = await current_loop.run_in_executor(ThreadPoolExecutor(), blacking_task)
    print(future)


def thread_name():
    print(f"當前執行緒名字:{threading.current_thread()}\n")


async def producer(queue,consumers):
    for data in range(10):
        print(f'生產者正在生產資料...{data}')
        await queue.put(data)
        await asyncio.sleep(1)
    for data in range(consumers):
        await queue.put(None)
        await queue.put(None)


async def consumer(queue,name):
    while True:
        print(f'{name}:消費者正在等待資料...')
        data = await queue.get()
        if data is None:
            print(f'{name}:任務結束')
            break
        print(f'{name}:消費者消費了資料: {data}')


def start_loop(loop):
    thread_name()
    asyncio.set_event_loop(loop)
    loop.run_forever()

async def blocking_async_task():
    await asyncio.sleep(5)
    thread_name()


def push_task_loop():
    loop_new = asyncio.new_event_loop()
    threading.Thread(target=start_loop, args=(loop_new,)).start()
    asyncio.run_coroutine_threadsafe(blocking_async_task(), loop_new)


async def new_thread_task():
    result = await asyncio.to_thread(blacking_task)
    print(result)


async def task_queue():
    queue = asyncio.Queue()
    await asyncio.gather(
        asyncio.ensure_future(producer(queue,3)),
        asyncio.ensure_future(consumer(queue,"consumer_0")),
        asyncio.ensure_future(consumer(queue,"consumer_1")),
        asyncio.ensure_future(consumer(queue,"consumer_2"))
    )


if __name__ == '__main__':
    # asyncio.run(task_run_in_one_executor())

    # asyncio.run(return_future())

    # push_task_loop()

    # asyncio.run(new_thread_task())

    asyncio.run(task_queue())

    pass


相關文章