1. 什么是asyncio?
asyncio是Python3.4引入的一个库,用于编写异步IO应用程序,可以实现高并发的处理,提升程序的效率和吞吐量。它采用的是单线程事件循环模型,避免了多线程的复杂性。
asyncio的核心是协程(coroutine),也是异步编程的基础。
import asyncio
async def my_coroutine():
print("Hello, World!")
loop = asyncio.get_event_loop()
loop.run_until_complete(my_coroutine())
上面的代码定义了一个协程函数,然后使用事件循环对象来运行这个协程。注意,这里使用的是run_until_complete()
方法来执行协程函数,也就是说这个方法将等待协程执行完成后返回结果。
2. asyncio中的异步编程
2.1 async/await语法
Python 3.5及以上版本引入了async/await
语法,在异步编程中使用起来更加方便。它与yield
语法类似,它将函数的控制权返回给事件循环,从而实现异步操作的调用。
async def my_coroutine():
print("Hello, World!")
async def another_coroutine():
await my_coroutine()
loop = asyncio.get_event_loop()
loop.run_until_complete(another_coroutine())
上面的代码定义了两个协程函数,第二个函数使用了await
关键字来等待第一个函数的执行结果。
2.2 asyncio模块中的事件循环
asyncio的事件循环是异步编程的核心,它提供了协程的任务调度和异步IO的支持。可以使用asyncio.get_event_loop()
函数来获取默认的事件循环对象。
loop = asyncio.get_event_loop()
loop.run_until_complete(my_coroutine())
loop.close()
上面的代码展示了如何创建、运行和关闭事件循环对象。
3. asyncio示例
3.1 asyncio爬虫
下面是一个使用asyncio实现的简单爬虫程序,它从网页中获取标题内容,然后输出到控制台:
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def get_title(loop, url):
async with aiohttp.ClientSession(loop=loop) as session:
html = await fetch(session, url)
title = html.split('
')[1].split(' ')[0]
print(title)
loop = asyncio.get_event_loop()
tasks = [get_title(loop, 'https://example.com') for i in range(10)]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
上面的代码使用了aiohttp库来获取网页内容,将获取标题的逻辑封装成了一个协程函数get_title()
,然后使用asyncio.wait()
方法将多个协程任务添加到事件循环中,等待它们完成。
3.2 asyncio多进程和多线程
asyncio支持将异步操作封装到子进程和子线程中,以提高异步IO应用程序的性能。
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def get_title(loop, url):
async with aiohttp.ClientSession(loop=loop) as session:
html = await fetch(session, url)
title = html.split('
')[1].split(' ')[0]
print(title)
async def main(loop):
async with aiohttp.ClientSession(loop=loop) as session:
url = 'https://example.com'
html = await fetch(session, url)
# 使用子进程
process = await asyncio.create_subprocess_exec(
'python', '-c', 'print(len(input()))',
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE)
stdout, stderr = await process.communicate(html.encode())
print("The length of the HTML page is:", stdout.decode())
# 使用子线程
result = await loop.run_in_executor(None, len, html)
print("The length of the HTML page is:", result)
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
loop.close()
上面的代码展示了如何在异步应用程序中使用子进程和子线程来运行异步操作,create_subprocess_exec()
方法和run_in_executor()
方法都是异步操作。
4. 结论
asyncio是Python中的一种协程模块,可以用于编写高并发的异步IO应用程序。它提供的语法简单、易于使用,可以减少多线程的复杂性,同时还支持将异步操作封装到子进程和子线程中,提高了应用程序的性能。