MST

星途 面试题库

面试题:网络编程下gevent库协程资源管理与异常处理

在使用gevent进行网络编程时,当有大量协程并发执行,如何有效管理资源以避免内存泄漏或性能瓶颈?同时,如果在协程执行网络请求过程中出现异常,如网络超时、连接错误等,怎样优雅地处理这些异常,保证程序的稳定性和可靠性?请结合代码说明处理方案。
28.7万 热度难度
后端开发网络编程

知识考点

AI 面试

面试题答案

一键面试

1. 资源管理

  • 控制协程数量:使用gevent.pool.Pool来限制并发协程的数量,避免过多协程占用大量内存。
import gevent
from gevent.pool import Pool

pool = Pool(100)  # 最多允许100个协程并发执行

def task():
    # 网络请求等任务逻辑
    pass

jobs = [pool.spawn(task) for _ in range(1000)]
gevent.joinall(jobs)
  • 及时释放资源:在协程执行完任务后,确保相关资源(如文件句柄、网络连接等)被正确关闭。例如在使用requests库进行网络请求时:
import gevent
import requests

def fetch_data(url):
    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功
        return response.json()
    finally:
        # 这里可以添加清理资源的代码,requests库在请求结束后会自动清理连接等资源
        pass

urls = ['http://example.com' for _ in range(100)]
jobs = [gevent.spawn(fetch_data, url) for url in urls]
gevent.joinall(jobs)

2. 异常处理

  • 捕获异常:在协程函数内部使用try - except块捕获网络请求过程中的异常。
import gevent
import requests

def fetch_data(url):
    try:
        response = requests.get(url, timeout = 5)  # 设置超时时间为5秒
        response.raise_for_status()
        return response.json()
    except requests.exceptions.Timeout:
        print(f"请求 {url} 超时")
    except requests.exceptions.ConnectionError:
        print(f"请求 {url} 连接错误")
    except requests.exceptions.HTTPError as http_err:
        print(f"请求 {url} 出现HTTP错误: {http_err}")
    except Exception as err:
        print(f"请求 {url} 出现其他错误: {err}")


urls = ['http://example.com' for _ in range(100)]
jobs = [gevent.spawn(fetch_data, url) for url in urls]
gevent.joinall(jobs)
  • 异常传播与集中处理:也可以将异常抛出,在joinall时统一处理。
import gevent
import requests

def fetch_data(url):
    response = requests.get(url, timeout = 5)
    response.raise_for_status()
    return response.json()


urls = ['http://example.com' for _ in range(100)]
jobs = [gevent.spawn(fetch_data, url) for url in urls]
try:
    gevent.joinall(jobs)
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError, requests.exceptions.HTTPError) as err:
    print(f"捕获到异常: {err}")