赞
踩
协程(Coroutine)是一种轻量级的线程,也被称为用户级线程或绿色线程。它是一种用户态的上下文切换方式,比内核态的线程切换更为轻量级,能够高效的支持大量并发操作。
Python 中的协程是通过 asyncio 模块实现的,使用协程可以带来以下好处:
总之,协程是一种高效、轻量级的并发编程方式,能够提高程序的性能,简化异步编程,使得控制流程更加灵活,是 Python 中重要的并发编程工具之一。
import asyncio async def task1(): await asyncio.sleep(1) print('Task 1 done') async def task2(): await asyncio.sleep(2) print('Task 2 done') async def main(): print('Starting tasks') # 并发执行 task1 和 task2 任务 await asyncio.gather(task1(), task2()) '''列表传参启动''' # tasks = [task1(), task2()] # 创建协程任务列表 # await asyncio.gather(*tasks) # 同时运行所有协程任务 print('All tasks done') asyncio.run(main())
也可以使用列表传参的方式将任务传进去启动
tasks = [task1(), task2()] # 创建协程任务列表
await asyncio.gather(*tasks) # 同时运行所有协程任务
运行结果
import asyncio import random async def producer(queue): while True: value = random.randint(0, 10) print(f"Produced: {value}") await queue.put(value) await asyncio.sleep(random.random()) async def consumer(queue): while True: value = await queue.get() print(f"Consumed: {value}") await asyncio.sleep(random.random()) async def main(): queue = asyncio.Queue() task_producer = asyncio.create_task(producer(queue)) task_consumer = asyncio.create_task(consumer(queue)) await asyncio.gather(task_producer, task_consumer) asyncio.run(main())
运行结果
在上面的代码中,我们定义了一个 producer 函数和一个 consumer
函数,它们都接受一个 asyncio.Queue
对象作为输入,并在其中实现协程的逻辑。其中 producer
函数会在队列中不断生成随机数,并将其放入队列中;consumer
函数则会不断从队列中取出随机数并进行消费。
在 main 函数中,我们首先创建了一个 asyncio.Queue
对象用于协程之间的通信,然后使用 asyncio.create_task
函数创建了两个任务,分别是生产者任务和消费者任务。最后,我们使用 asyncio.gather
函数来运行这两个任务,当其中任何一个任务完成时,main 函数也会结束。
需要注意的是,当我们使用协程时,需要使用 await
关键字来挂起协程的执行,等待其他协程的执行或者等待 I/O 操作完成。同时,在协程中不应该使用阻塞式的操作,比如 time.sleep()
,而应该使用异步 I/O 操作,比如 asyncio.sleep()
。
import asyncio import random async def producer(queue): while True: value = random.randint(0, 10) print(f"Produced: {value}") await queue.put(value) await asyncio.sleep(random.random()) async def consumer(queue): while True: value = await queue.get() print(f"Consumed: {value}") await asyncio.sleep(random.random()) async def main(): queue = asyncio.Queue() '''方法一''' # task_producer = asyncio.create_task(producer(queue)) # task_consumer = asyncio.create_task(consumer(queue)) # await asyncio.gather(task_producer, task_consumer) '''方法二:直接启动''' # await asyncio.wait([producer(queue), consumer(queue)]) '''方法三''' task_producer = asyncio.ensure_future(producer(queue)) task_consumer = asyncio.ensure_future(consumer(queue)) await asyncio.wait([task_producer(queue), task_consumer(queue)]) asyncio.run(main())
以上协程的几种启动方式的的区别在于它们等待任务完成的方式不同。
await asyncio.gather(task_producer, task_consumer)
await asyncio.wait([producer(queue), consumer(queue)])
则是将多个协程对象(通过列表进行传递)传递给 asyncio.wait()
函数,这个函数也会等待多个协程同时完成。不同的是,asyncio.wait()
函数会返回两个集合(即 done 和pending),done 集合包含已经完成的任务,pending 集合包含还未完成的任务。因此可以通过遍历 done集合取得协程的结果。asyncio.ensure_future()
可以将协程函数包装为一个 Future对象,它可以被添加到事件循环中进行异步执行。与直接调用协程函数不同,使用 asyncio.ensure_future() 会创建一个Future 对象并返回它,这个对象可以被传递到其他地方进行管理和操作。asyncio.ensure_future()
的主要优势是可以在多个协程之间共享对象,使得协程之间可以协同工作。同时,它还可以使协程函数更加可读性高,在协程之间传递数据时也更加方便。总的来说
asyncio.gather()
更加简单易用,适合并发执行多个任务并等待它们全部完成的情况。asyncio.wait()
则更加灵活,并且可以实时获取任务的执行结果。asyncio.ensure_future()
是一种更加通用的方法,适用于大多数协程编程的情况,但是在某些情况下,使用直接调用协程函数和 await 可能更加简单和有效。注意,在 Python 3.7 以前,我们需要使用 asyncio.get_event_loop().run_until_complete()
函数来运行协程任务。但在 Python 3.7
及以后的版本中,我们可以使用更为简洁的 asyncio.run()
函数来运行协程任务。
示例代码如下:
import asyncio import random async def producer(queue): while True: value = random.randint(0, 10) print(f"Produced: {value}") await queue.put(value) await asyncio.sleep(random.random()) async def consumer(queue): while True: value = await queue.get() print(f"Consumed: {value}") await asyncio.sleep(random.random()) async def main(): queue = asyncio.Queue() '''方法一''' # task_producer = asyncio.create_task(producer(queue)) # task_consumer = asyncio.create_task(consumer(queue)) # await asyncio.gather(task_producer, task_consumer) '''方法二:直接启动''' # await asyncio.wait([producer(queue), consumer(queue)]) '''方法三''' task_producer = asyncio.ensure_future(producer(queue)) task_consumer = asyncio.ensure_future(consumer(queue)) await asyncio.wait([task_producer(queue), task_consumer(queue)]) '''协程启动的方式一''' # asyncio.run(main()) '''协程启动的方式二''' new_loop = asyncio.new_event_loop() asyncio.set_event_loop(new_loop) new_loop.run_until_complete(main())
总之,协程是一种高效、轻量级的并发编程方式,能够提高程序的性能,简化异步编程,使得控制流程更加灵活,是 Python 中重要的并发编程工具之一。
以上就是关于Python - 协程基本使用的介绍,希望对你有所帮助,谢谢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。