python 实现socket服务端并发的四种方式


Posted in Python onDecember 14, 2020

多进程&多线程

服务端:多进程和多线程的开启方式相同。

缺点:<1> 由于Cpython的GIL,导致同一时间无法运行多个线程;<2> 不可能无限开进进程或线程

解决办法:多进程、concurrent.futures.ProcessPoolExecutor、线程池

import socket
from multiprocessing import Process
from threading import Thread


class MyTcpServer:
  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)

  def wait_accept(self):
    conn, addr = self.server.accept()
    return conn, addr

  def handle_request(self, conn):
    while 1:
      try:
        data = conn.recv(1024)
        if not data: break
        conn.send(data.upper())
      except Exception as e:
        print(e)
        break
    conn.close()


if __name__ == '__main__':
  server = MyTcpServer('127.0.0.1', 8888)
  while 1:
    conn, addr = server.wait_accept()
    p = Process(target=server.handle_request, args=(conn, ))	# 创建一个进程
    p.start()	# 告诉操作提供,开启这个进程

进程池&线程池

异步提交任务,支持异步接收返回结果(submit返回一个futures对象,调用add_done_callback方法)

import socket
from concurrent.futures import ProcessPoolExecutor
# from concurrent.futures import ThreadPoolExecutor


class MyTcpServer:
  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)

  def wait_accept(self):
    conn, addr = self.server.accept()
    return conn, addr

  def handle_request(self, conn):
    while 1:
      try:
        data = conn.recv(1024)
        if not data: break
        conn.send(data.upper())
      except Exception as e:
        print(e)
        break
    conn.close()


if __name__ == '__main__':
  server = MyTcpServer('127.0.0.1', 8888)
  pool = ProcessPoolExecutor(5)    # 5个进程一直服务

  while 1:
    conn, addr = server.wait_accept()
    pool.submit(server.handle_request, conn)	# 异步提交任务

socketserver

优点:简化socket服务端创建流程。
提供服务端串行和并发两种服务模式(TCPServer,ThreadingTCPServer)
缺点:windows上无法使用多进程实现并发

import socketserver


class MyTcpHandler(socketserver.BaseRequestHandler):
  def handle(self):		# 通信循环
    while 1:
      try:
        data = self.request.recv(1024)
        if not data: break
        self.request.send(data.upper())
      except Exception as e:
        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切换,提高程序运行效率

from gevent import spawn, monkey;monkey.patch_all()		# 猴子补丁,补丁:常规IO
import socket


class MyTcpServer:
  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本地

  def wait_accept(self):
    while 1:
      conn, addr = self.server.accept()
      self.spawn(self.handle_request, conn)	# 检测 handle_request的io

  def handle_request(self, conn):
    while 1:
      try:
        data = conn.recv(1024)
        if not data: break
        conn.send(data.upper())
      except Exception as e:
        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服务端并发的四种方式的详细内容,更多关于python socket服务端并发的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python实现一次创建多级目录的方法
May 15 Python
Python变量作用范围实例分析
Jul 07 Python
详解Python自建logging模块
Jan 29 Python
python文本数据相似度的度量
Mar 12 Python
pandas Dataframe行列读取的实例
Jun 08 Python
实时获取Python的print输出流方法
Jan 07 Python
对python实现模板生成脚本的方法详解
Jan 30 Python
python如何实现不可变字典inmutabledict
Jan 08 Python
Pytorch模型转onnx模型实例
Jan 15 Python
python中对二维列表中一维列表的调用方法
Jun 07 Python
python产生模拟数据faker库的使用详解
Nov 04 Python
python“静态”变量、实例变量与本地变量的声明示例
Nov 13 Python
linux centos 7.x 安装 python3.x 替换 python2.x的过程解析
Dec 14 #Python
Python获取指定网段正在使用的IP
Dec 14 #Python
python利用pytesseract 实现本地识别图片文字
Dec 14 #Python
python 利用百度API识别图片文字(多线程版)
Dec 14 #Python
python3中for循环踩过的坑记录
Dec 14 #Python
Python 数据分析之逐块读取文本的实现
Dec 14 #Python
Python 2.6.6升级到Python2.7.15的详细步骤
Dec 14 #Python
You might like
深入PHP curl参数的详解
2013/06/17 PHP
PHP检测数据类型的几种方法(总结)
2017/03/04 PHP
php抽象类和接口知识点整理总结
2019/08/02 PHP
Yii框架操作cookie与session的方法实例详解
2019/09/04 PHP
asp批量修改记录的代码
2008/06/25 Javascript
JQuery 学习笔记 选择器之五
2009/07/23 Javascript
jquery animate 动画效果使用说明
2009/11/04 Javascript
判断对象是否Window的实现代码
2012/01/10 Javascript
JavaScript数值转换的三种方式总结
2014/07/31 Javascript
浅谈JavaScript数据类型及转换
2015/02/28 Javascript
JavaScript实现微信号随机切换代码
2018/03/09 Javascript
JS实现二维数组横纵列转置的方法
2018/04/17 Javascript
弱类型语言javascript开发中的一些坑实例小结【变量、函数、数组、对象、作用域等】
2019/08/07 Javascript
详细分析vue响应式原理
2020/06/22 Javascript
[02:41]2015国际邀请赛中国区预选赛观战指南
2015/05/20 DOTA
Python输入二维数组方法
2018/04/13 Python
django连接mysql配置方法总结(推荐)
2018/08/18 Python
python获取微信小程序手机号并绑定遇到的坑
2018/11/19 Python
python基于SMTP协议发送邮件
2019/05/31 Python
详解Python绘图Turtle库
2019/10/12 Python
Python @property装饰器原理解析
2020/01/22 Python
Python列表list操作相关知识小结
2020/01/29 Python
PyQt5+python3+pycharm开发环境配置教程
2020/03/24 Python
python redis存入字典序列化存储教程
2020/07/16 Python
mui几种页面跳转方式对比总结概括
2017/08/18 HTML / CSS
Topshop法国官网:英国快速时尚品牌
2018/04/08 全球购物
英国当代时尚和街头服饰店:18montrose
2018/12/15 全球购物
如何强制垃圾回收
2015/10/06 面试题
请解释virtual关键字的含义
2015/06/17 面试题
市三好学生主要事迹
2014/01/28 职场文书
《花的勇气》教后反思
2014/02/12 职场文书
小学毕业典礼演讲稿
2014/09/09 职场文书
2014年小学教师工作总结
2014/11/10 职场文书
2014年小学体育工作总结
2014/12/11 职场文书
学校艾滋病宣传活动总结
2015/05/09 职场文书
2016年党支部公开承诺书
2016/03/25 职场文书