浅谈Python协程

协程是一种非常轻量级的线程,也称为微线程或者用户空间线程。协程与线程不同的是,线程由操作系统进行调度,而协程是程序员自行调度,因此切换的代价更低。

浅谈Python协程

什么是协程

协程是一种非常轻量级的线程,也称为微线程或者用户空间线程。协程与线程不同的是,线程由操作系统进行调度,而协程是程序员自行调度,因此切换的代价更低。

协程中包含多个协程对象,每个协程对象都应该包含一个状态机,也就是说,协程只有在切换时才会保存和恢复状态。

Python中的协程是通过asyncio库来实现的,asyncio是Python3.4中引入的标准库,提供了一种写异步代码的方案。

协程的优势

协程的优势主要在于以下几点:

  1. 更加高效的切换。协程的切换是用户空间的,避免了系统调用和上下文切换等开销。
  2. 更加轻量级的线程。线程的启动和销毁需要开销很大的系统调用,而协程的启动和销毁只需要简单的对象构造和析构操作。
  3. 更好的可读性和可维护性。协程的代码结构更加清晰,没有锁和同步的问题,代码可读性和可维护性都更高。

如何使用协程

Python中使用协程需要用到asyncawait这两个关键字。

async关键字用于定义一个协程函数,表示这个函数是一个异步函数,可以使用await来进行挂起。

await关键字用于挂起一个协程,直到协程内部的异步操作执行完成。

下面是一个使用协程的示例代码:

import asyncio

async def hello():
    print('Hello')
    await asyncio.sleep(1)
    print('World')

async def main():
    tasks = [hello(), hello()]
    await asyncio.gather(*tasks)

if __name__ == '__main__':
    asyncio.run(main())

这段代码中,hello函数是一个协程函数,它包含了一个异步操作asyncio.sleep,表示等待1秒后再继续执行后续代码。

main函数也是一个协程函数,它调用了两个hello函数,并使用asyncio.gather等待所有任务执行完毕。

运行以上代码可以看到输出结果为:

Hello
Hello
World
World

协程的应用场景

协程的应用场景非常广泛,常见的应用场景包括:

  1. 服务器中的网络编程,协程可以代替传统的多线程编程模型,提高并发性能。
  2. I/O密集型任务,例如文件读写、网络通信等,使用协程可以避免I/O等待时的大量资源浪费。
  3. CPU密集型任务,例如加密、解密、图像处理等,虽然协程无法真正地并行执行,但是使用协程可以提高CPU利用率,避免阻塞等待。

示例

下面我们来看一个使用协程进行爬虫的示例代码:

import asyncio
import aiohttp

async def get(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    url_list = [
        'https://www.baidu.com',
        'https://www.jd.com',
        'https://www.taobao.com',
    ]

    tasks = []
    for url in url_list:
        tasks.append(asyncio.create_task(get(url)))

    for task in asyncio.as_completed(tasks):
        result = await task
        print(f'URL: {result[:20]}')

if __name__ == '__main__':
    asyncio.run(main())

在这个示例代码中,我们定义了一个get函数,用于通过aiohttp模块发起HTTP GET请求,并返回响应内容。

main函数中创建了三个URL的列表,并通过循环创建相应的协程任务。使用asyncio.as_completed函数等待所有任务完成,并获取结果,然后输出结果的前20个字节。

运行以上代码可以看到输出结果为:

URL: <html><head><meta http
URL: <!DOCTYPE html>\n<htm
URL: <!DOCTYPE html>\n<htm

可以看到,我们成功通过协程并发地发起了三个HTTP GET请求,并获取了相应的响应数据。

总结

协程是一种轻量级的线程,使用Python的asyncio库可以很方便地实现协程。协程的优势在于更高的执行效率和更好的可读性和可维护性。协程的应用场景包括服务器中的网络编程、I/O密集型任务、CPU密集型任务等。

本文标题为:浅谈Python协程

基础教程推荐