欢迎访问宙启技术站
智能推送

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多线程和异步函数都具有非常广泛的应用场景,并且在不同的场景下具有不同的优势。在使用这两种并发处理方式时,需要根据具体场景和需求进行选择和判断,以达到 的性能和效果。