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中mechanize库的简单使用示例
Jan 10 Python
python统计一个文本中重复行数的方法
Nov 19 Python
利用Tkinter(python3.6)实现一个简单计算器
Dec 21 Python
pip matplotlib报错equired packages can not be built解决
Jan 06 Python
详解Django中六个常用的自定义装饰器
Jul 04 Python
Appium+Python自动化测试之运行App程序示例
Jan 23 Python
python实现Virginia无密钥解密
Mar 20 Python
在django view中给form传入参数的例子
Jul 19 Python
python requests抓取one推送文字和图片代码实例
Nov 04 Python
PyCharm 2019.3发布增加了新功能一览
Dec 08 Python
Python3实现个位数字和十位数字对调, 其乘积不变
May 03 Python
解决pytorch-gpu 安装失败的记录
May 24 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
IIS7.X配置PHP运行环境小结
2011/06/09 PHP
php输出指定时间以前时间格式的方法
2015/03/21 PHP
在Laravel中实现使用AJAX动态刷新部分页面
2019/10/15 PHP
javascript 进度条 实现代码
2009/07/30 Javascript
jQuery 判断元素上是否绑定了事件
2009/10/28 Javascript
jQuery toggle()设置CSS样式
2009/11/05 Javascript
jquery1.4后 jqDrag 拖动 不可用
2010/02/06 Javascript
JavaScript操纵窗口的方法小结
2013/06/28 Javascript
js与jquery回车提交的方法
2015/02/03 Javascript
JavaScript更改原始对象valueOf的方法
2015/03/19 Javascript
Jquery实现动态切换图片的方法
2015/05/18 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
JS中使用 after 伪类清除浮动实例
2017/03/01 Javascript
详解Node.js开发中的express-session
2017/05/19 Javascript
JavaScript实现的数字与字符串转换功能示例
2017/08/23 Javascript
详解webpack运行Babel教程
2018/06/13 Javascript
jQuery中$原理实例分析
2018/08/13 jQuery
Vue-cli打包后部署到子目录下的路径问题说明
2020/09/02 Javascript
vue实现点击出现操作弹出框的示例
2020/11/05 Javascript
[38:32]DOTA2上海特级锦标赛A组资格赛#2 Secret VS EHOME第二局
2016/02/26 DOTA
Python 3.6 性能测试框架Locust安装及使用方法(详解)
2017/10/11 Python
python中的tcp示例详解
2018/12/09 Python
Python爬取爱奇艺电影信息代码实例
2019/11/26 Python
pytorch中nn.Conv1d的用法详解
2019/12/31 Python
解决PyCharm IDE环境下,执行unittest不生成测试报告的问题
2020/09/03 Python
Django返回HTML文件的实现方法
2020/09/17 Python
python实现快速文件格式批量转换的方法
2020/10/16 Python
CSS3绘制超炫的上下起伏波动进度加载动画
2016/04/21 HTML / CSS
HTML5 input新增type属性color颜色拾取器的实例代码
2018/08/27 HTML / CSS
澳大利亚设计师服装在线:MISHA
2019/10/07 全球购物
教师个人剖析材料
2014/02/05 职场文书
工资收入证明样本(5篇)
2014/09/16 职场文书
2015年招商引资工作总结
2015/04/25 职场文书
2015年共青团工作总结
2015/05/15 职场文书
使用Golang的channel交叉打印两个数组的操作
2021/04/29 Golang
Python 键盘事件详解
2021/11/11 Python