MST
星途 面试题库

面试题:Python Socket编程之并发处理

在Python中,使用Socket模块实现一个支持多客户端并发连接的TCP服务器。服务器要能处理每个客户端独立的请求,计算客户端发送过来的整数列表的平均值,并返回给客户端。请阐述你选择的并发模型(如多线程、多进程、异步I/O等)及其优缺点,同时给出完整代码实现。
26.2万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

并发模型选择及优缺点

  1. 多线程
    • 优点:线程间共享进程资源,创建和销毁开销相对较小,适合I/O密集型任务,在Python中可以方便地使用threading模块实现。
    • 缺点:由于Python的全局解释器锁(GIL),在CPU密集型任务中无法利用多核优势,且线程同步需要小心处理,否则容易出现死锁等问题。
  2. 多进程
    • 优点:每个进程有独立的内存空间,不存在GIL问题,可以充分利用多核CPU,适合CPU密集型任务。
    • 缺点:进程间通信相对复杂,创建和销毁开销较大,占用资源较多。
  3. 异步I/O
    • 优点:通过事件循环和协程,能在单线程内处理多个I/O操作,高效利用资源,非常适合I/O密集型任务,代码简洁,无需复杂的线程或进程管理。
    • 缺点:编程模型相对新,对于习惯传统同步编程的开发者可能不太容易理解,调试相对困难,对CPU密集型任务支持不佳。

这里选择多线程并发模型,因为计算平均值属于简单计算,主要的开销在于网络I/O,多线程在I/O密集场景有较好表现且实现相对简单。

代码实现

import socket
import threading


def handle_client(client_socket):
    try:
        data = client_socket.recv(1024).decode('utf - 8')
        num_list = list(map(int, data.split(',')))
        avg = sum(num_list) / len(num_list) if num_list else 0
        client_socket.send(str(avg).encode('utf - 8'))
    except Exception as e:
        print(f"Error handling client: {e}")
    finally:
        client_socket.close()


def start_server():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('127.0.0.1', 8888))
    server_socket.listen(5)
    print("Server is listening on port 8888...")

    while True:
        client_socket, client_addr = server_socket.accept()
        print(f"Accepted connection from {client_addr}")
        client_thread = threading.Thread(target=handle_client, args=(client_socket,))
        client_thread.start()


if __name__ == "__main__":
    start_server()
  1. handle_client函数:负责处理单个客户端连接。接收客户端发送的数据,将其转换为整数列表并计算平均值,然后将平均值返回给客户端。如果出现异常,打印错误信息并关闭连接。
  2. start_server函数:创建TCP服务器套接字,绑定到本地地址和端口8888并开始监听。每当有新客户端连接时,创建一个新线程来处理该客户端。
  3. if __name__ == "__main__":确保start_server函数在直接运行脚本时被调用。