12.7 创建线程池来处理用户客户端链接
- concurrent.futures库中包含一个ThreadPoolExecutor类可以实现这个目标。我们来创建一个简单的TCP服务器,使用线程池来服务客户端
from socket import AF_INET,SOCK_STREAM,socket
from concurrent.futures import ThreadPoolExecutor
def echo_client(sock,client_addr):
print('got connection from',client_addr)
while True:
msg = sock.recv(65536)
if not msg:
break
sock.sendall(msg)
print('client closed')
sock.close()
def echo_server(addr):
pool = ThreadPoolExecutor(128)
sock = socket(AF_INET,SOCK_STREAM)
sock.bind(addr)
sock.listen(5)
while True:
client_sock,client_addr=sock.accept()
pool.submit(echo_client,client_sock,client_addr)
echo_server(('',5000))
from socket import AF_INET,SOCK_STREAM,socket
from concurrent.futures import ThreadPoolExecutor
from threading import Thread
from queue import Queue
def echo_client(q):
sock,client_addr = q.get()
print('got connection from',client_addr)
while True:
msg = sock.recv(65536)
if not msg:
break
sock.sendall(msg)
print('client closed')
sock.close()
def echo_server(addr,nworkers):
q = Queue()
for n in range(nworkers):
t = Thread(target=echo_client,args=(q,))
t.daemon = True
t.start()
sock = socket(AF_INET,SOCK_STREAM)
sock.bind(addr)
sock.listen(5)
while True:
client_sock,client_addr=sock.accept()
q.put(client_sock,client_addr)
echo_server(('',5000),120)
- 我们大多数情况下会使用ThreadPoolExecutor而不是手动实现线程池。这么做的优势在于使得任务的提交者能够更容易从调用函数中取得结果。
网友评论