多线程
- 原理:在Python中,
threading
模块可用于创建多线程。每个线程可以处理一个客户端连接,这样就可以实现并发处理。
- 示例代码:
import socket
import threading
def handle_client(client_socket):
while True:
data = client_socket.recv(1024)
if not data:
break
client_socket.sendall(data)
client_socket.close()
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 8888))
server_socket.listen(5)
while True:
client_socket, addr = server_socket.accept()
client_thread = threading.Thread(target=handle_client, args=(client_socket,))
client_thread.start()
- 资源管理:
- 资源泄漏:线程可能因为异常退出而没有正确关闭套接字等资源。解决方案是在
try - except - finally
块中处理,在finally
中关闭资源。例如:
def handle_client(client_socket):
try:
while True:
data = client_socket.recv(1024)
if not data:
break
client_socket.sendall(data)
except Exception as e:
print(f"Error: {e}")
finally:
client_socket.close()
- 性能瓶颈:Python的全局解释器锁(GIL)会限制多线程在CPU密集型任务上的性能。对于I/O密集型的TCP服务器,影响相对较小,但对于一些可能涉及计算的任务,可考虑使用
concurrent.futures.ThreadPoolExecutor
来管理线程池,避免创建过多线程。
多进程
- 原理:
multiprocessing
模块用于创建多进程。每个进程有自己独立的内存空间和Python解释器实例,可有效避开GIL限制。
- 示例代码:
import socket
import multiprocessing
def handle_client(client_socket):
while True:
data = client_socket.recv(1024)
if not data:
break
client_socket.sendall(data)
client_socket.close()
if __name__ == '__main__':
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 8888))
server_socket.listen(5)
while True:
client_socket, addr = server_socket.accept()
client_process = multiprocessing.Process(target=handle_client, args=(client_socket,))
client_process.start()
- 资源管理:
- 资源泄漏:进程创建和销毁开销较大,若进程异常退出未正确清理资源,如文件描述符等,可能导致资源泄漏。可以通过在进程中设置信号处理函数,捕获异常并清理资源。例如:
import signal
def handle_client(client_socket):
def cleanup(signum, frame):
client_socket.close()
signal.signal(signal.SIGTERM, cleanup)
signal.signal(signal.SIGINT, cleanup)
while True:
data = client_socket.recv(1024)
if not data:
break
client_socket.sendall(data)
client_socket.close()
- 性能瓶颈:过多进程会消耗大量系统资源,如内存、文件描述符等。可以使用进程池
multiprocessing.Pool
来管理进程数量,根据系统资源情况合理设置进程池大小。
异步I/O(asyncio)
- 原理:
asyncio
是Python用于编写异步代码的库,通过事件循环、协程和异步I/O实现高效的并发处理。
- 示例代码:
import asyncio
async def handle_client(reader, writer):
while True:
data = await reader.read(1024)
if not data:
break
writer.write(data)
await writer.drain()
writer.close()
await writer.wait_closed()
async def main():
server = await asyncio.start_server(handle_client, '0.0.0.0', 8888)
async with server:
await server.serve_forever()
if __name__ == '__main__':
asyncio.run(main())
- 资源管理:
- 资源泄漏:如果协程没有正确处理异常,可能导致资源未释放,如未关闭的连接。可以在协程中使用
try - except - finally
块处理异常,在finally
中关闭连接。例如:
async def handle_client(reader, writer):
try:
while True:
data = await reader.read(1024)
if not data:
break
writer.write(data)
await writer.drain()
except Exception as e:
print(f"Error: {e}")
finally:
writer.close()
await writer.wait_closed()
- 性能瓶颈:
asyncio
本身性能较高,但如果事件循环中阻塞操作过多,会影响整体性能。要确保所有I/O操作都是异步的,避免在协程中进行长时间的同步计算。若有计算需求,可使用loop.run_in_executor
将计算任务提交到线程池或进程池执行。