多线程和协程都属于IO密集型,我通过以下用例测试多线程和协程的实际速率对比。
实例:通过socket客户端以多线程并发模式请求不同服务器端(这里服务器端分2种写法:第一种服务器通过协程实现,第二种服务器通过多线程实现)的访问速率
第一种服务器端写法:通过gevent实现
import socket
import gevent
from gevent import socket, monkey
monkey.patch_all() def server(port): # socket服务器函数
s = socket.socket()
s.bind(('localhost', port))
s.listen()
print('start server listen:')
while True:
conn, addr = s.accept()
gevent.spawn(handle_request, conn) # 协程模式实现交互 def handle_request(conn):
try:
while True:
data = conn.recv(1024)
print('recv:',data)
conn.send(data)
if not data:
conn.shutdown(socket.SHUT_WR)
except Exception as e:
print(e)
finally:
conn.close()
if __name__ == '__main__':
server(9999)
gevent协程服务器模式
第二种服务器端写法:通过多线程实现
import socketserver class Myhandler(socketserver.BaseRequestHandler):
def handle(self):
print(self)
while True:
print('开始监听客户端连接')
data = self.request.recv(1024)
# if len(data) == 0:
# exit('client close')
print('client data:', data)
self.request.send(data.upper()) if __name__ == '__main__':
s = socketserver.ThreadingTCPServer(('localhost', 9999), Myhandler) # 多线程
s.serve_forever()
多线程服务器模式
客户端:
import socket, time
import threading def client():
c = socket.socket()
c.connect(('localhost',9999))
count = 0
while count < 10:
c.send(("hello %s" % count).encode('utf-8'))
data = c.recv(1024)
print('recv from server:%s' % data)
count += 1
c.close() res_l = []
start_time = time.time()
for i in range(100):
t = threading.Thread(target=client)
t.start()
res_l.append(t)
for j in res_l:
j.join()
end_time = time.time()
print('finish,run time:', end_time-start_time)
socket客户端
结果:客户端每次运行,自动生成100个线程并发执行,每个线程自循环10次访问,对协程模式服务器的执行一次时长为: 0.17600011825561523秒, 对多线程服务器执行一次时长为:1.312999963760376 秒,通过结果对比协程模式实现的socket服务器处理速率远远高于多线程服务器