MST

星途 面试题库

面试题:Python多线程TCP服务器的资源管理与优化

在Python多线程TCP服务器场景下,当处理大量并发连接时,可能会出现资源耗尽(如文件描述符用尽)的问题。请描述你会如何优化代码来避免这类问题,并且给出相应的优化措施的Python代码示例,包括但不限于线程池的使用、资源回收机制等。
11.4万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
  1. 优化思路
    • 线程池的使用:创建线程池可以避免频繁创建和销毁线程带来的开销,并且可以限制同时活跃的线程数量,防止过多线程耗尽系统资源。
    • 资源回收机制:及时关闭不再使用的文件描述符,在Python中,使用with语句可以自动管理资源的生命周期,确保文件描述符在使用完毕后被正确关闭。
    • 连接管理:合理设置TCP连接的超时时间,避免长时间占用资源的无效连接。同时,对连接进行复用,减少新连接创建的频率。
  2. 代码示例
import socket
import threading
from concurrent.futures import ThreadPoolExecutor


def handle_connection(client_socket, client_address):
    try:
        with client_socket:
            while True:
                data = client_socket.recv(1024)
                if not data:
                    break
                # 处理接收到的数据
                client_socket.sendall(data)
    except Exception as e:
        print(f"处理连接 {client_address} 时出错: {e}")


def start_server():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_address = ('0.0.0.0', 12345)
    server_socket.bind(server_address)
    server_socket.listen(100)
    print(f"服务器在 {server_address} 监听")

    executor = ThreadPoolExecutor(max_workers = 100)
    try:
        while True:
            client_socket, client_address = server_socket.accept()
            executor.submit(handle_connection, client_socket, client_address)
    except KeyboardInterrupt:
        print("服务器停止")
    finally:
        server_socket.close()
        executor.shutdown(wait = True)


if __name__ == "__main__":
    start_server()

在上述代码中: - ThreadPoolExecutor 创建了一个线程池,max_workers 设置了线程池中的最大线程数,避免过多线程占用资源。 - handle_connection 函数中使用 with client_socket 确保 client_socket 在使用完毕后自动关闭,释放文件描述符资源。 - server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 允许服务器在程序重新启动时重用相同的地址和端口,提高资源利用率。