Python多线程和异步函数实现的应用举例
发布时间:2023-06-13 05:52:36
Python多线程和异步函数是Python语言中非常常见的两种并发处理方式。多线程利用CPU的多核优势,可以同时执行多个任务,提高程序的运行效率。而异步函数则是一种避免阻塞线程的方式,通过将任务挂起,等待I/O操作结束后再继续执行,从而提高程序的性能。下面将分别介绍这两种并发处理方式的应用举例。
1. 多线程的应用举例
(1)网络爬虫
网络爬虫是一种常见的需要大量网络I/O的场景,使用多线程可以同时对多个网页进行爬取,提高爬取速度。例如,下面的代码演示了如何使用多线程爬取豆瓣电影Top250的网页内容并保存到本地文件。
import threading
import requests
def download(url, file_name):
req = requests.get(url)
with open(file_name, 'wb') as f:
f.write(req.content)
if __name__ == '__main__':
urls = [
f'https://movie.douban.com/top250?start={i * 25}' for i in range(10)
]
threads = []
for i, url in enumerate(urls):
file_name = f'movie_{i + 1}.html'
thread = threading.Thread(target=download, args=(url, file_name))
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
(2)图像处理
图像处理是一种需要大量CPU计算的场景,使用多线程可以将图像处理任务分配给多个核心同时进行,提高处理速度。例如,下面的代码演示了如何使用多线程对图片进行压缩和旋转操作。
import threading
from PIL import Image
def compress(image_path, output_path):
img = Image.open(image_path)
img.save(output_path, quality=70)
def rotate(image_path, output_path):
img = Image.open(image_path)
img.rotate(45).save(output_path)
if __name__ == '__main__':
image_path = 'image.jpg'
output_path1 = 'image_compressed.jpg'
output_path2 = 'image_rotated.jpg'
thread1 = threading.Thread(target=compress, args=(image_path, output_path1))
thread2 = threading.Thread(target=rotate, args=(image_path, output_path2))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
2. 异步函数的应用举例
(1)网络应用开发
网络应用开发中经常需要处理大量的I/O请求,使用异步函数可以避免线程阻塞,提高处理效率。例如,下面的代码演示了如何使用异步函数处理HTTP请求。
import asyncio
import aiohttp
async def download(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
content = await response.read()
print(content)
if __name__ == '__main__':
urls = [
f'https://www.baidu.com/s?wd={i}' for i in range(10)
]
loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(download(url)) for url in urls]
loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
(2)数据库操作
数据库操作通常需要与网络I/O进行配合,使用异步函数可以将数据库操作挂起等待结果返回,避免线程阻塞。例如,下面的代码演示了如何使用异步函数对MySQL数据库进行查询操作。
import asyncio
import aiomysql
async def select(table, **kwargs):
async with aiomysql.create_pool(host='localhost',
port=3306,
user='root',
password='root',
db='test',
loop=loop) as conn:
async with conn.cursor() as cur:
sql = f"SELECT * FROM {table} WHERE {' AND '.join([f'{k}={v}' for k,v in kwargs.items()])}"
await cur.execute(sql)
results = await cur.fetchall()
print(results)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(select('user', name=f'user{i}', age=i)) for i in range(10)]
loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
综上所述,Python多线程和异步函数都具有非常广泛的应用场景,并且在不同的场景下具有不同的优势。在使用这两种并发处理方式时,需要根据具体场景和需求进行选择和判断,以达到 的性能和效果。
