python 实现socket服务端并发的四种方式
多进程&多线程
服务端:多进程和多线程的开启方式相同。
缺点:<1>由于Cpython的GIL,导致同一时间无法运行多个线程;<2>不可能无限开进进程或线程
解决办法:多进程、concurrent.futures.ProcessPoolExecutor、线程池
importsocket frommultiprocessingimportProcess fromthreadingimportThread classMyTcpServer: def__init__(self,ip,port): self.ip=ip self.port=port self.server=socket.socket() self.server.bind((self.ip,self.port)) self.server.listen(5) defwait_accept(self): conn,addr=self.server.accept() returnconn,addr defhandle_request(self,conn): while1: try: data=conn.recv(1024) ifnotdata:break conn.send(data.upper()) exceptExceptionase: print(e) break conn.close() if__name__=='__main__': server=MyTcpServer('127.0.0.1',8888) while1: conn,addr=server.wait_accept() p=Process(target=server.handle_request,args=(conn,)) #创建一个进程 p.start() #告诉操作提供,开启这个进程
进程池&线程池
异步提交任务,支持异步接收返回结果(submit返回一个futures对象,调用add_done_callback方法)
importsocket fromconcurrent.futuresimportProcessPoolExecutor #fromconcurrent.futuresimportThreadPoolExecutor classMyTcpServer: def__init__(self,ip,port): self.ip=ip self.port=port self.server=socket.socket() self.server.bind((self.ip,self.port)) self.server.listen(5) defwait_accept(self): conn,addr=self.server.accept() returnconn,addr defhandle_request(self,conn): while1: try: data=conn.recv(1024) ifnotdata:break conn.send(data.upper()) exceptExceptionase: print(e) break conn.close() if__name__=='__main__': server=MyTcpServer('127.0.0.1',8888) pool=ProcessPoolExecutor(5)#5个进程一直服务 while1: conn,addr=server.wait_accept() pool.submit(server.handle_request,conn) #异步提交任务
socketserver
优点:简化socket服务端创建流程。
提供服务端串行和并发两种服务模式(TCPServer,ThreadingTCPServer)
缺点:windows上无法使用多进程实现并发
importsocketserver classMyTcpHandler(socketserver.BaseRequestHandler): defhandle(self): #通信循环 while1: try: data=self.request.recv(1024) ifnotdata:break self.request.send(data.upper()) exceptExceptionase: print(e) break self.request.close() if__name__=='__main__': ip_port='127.0.0.1',8888 server=socketserver.ThreadingTCPServer(ip_port,MyTcpHandler)#异步处理 server.serve_forever() #连接循环
协程
优点:单线程内实现并发,代码级别模拟IO切换,提高程序运行效率
fromgeventimportspawn,monkey;monkey.patch_all() #猴子补丁,补丁:常规IO importsocket classMyTcpServer: def__init__(self,ip,port,my_spawn): self.ip=ip self.port=port self.server=socket.socket() self.server.bind((self.ip,self.port)) self.server.listen(5) self.spawn=my_spawn #保存spawn本地 defwait_accept(self): while1: conn,addr=self.server.accept() self.spawn(self.handle_request,conn) #检测handle_request的io defhandle_request(self,conn): while1: try: data=conn.recv(1024) ifnotdata:break conn.send(data.upper()) exceptExceptionase: print(e) break conn.close() if__name__=='__main__': server=MyTcpServer('127.0.0.1',8888,spawn) g1=server.spawn(server.wait_accept) #检测wait_accept的io g1.join() #等待g1运行结束,即一直在循环检测io
以上就是python实现socket服务端并发的四种方式的详细内容,更多关于pythonsocket服务端并发的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。