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 05 Python
Django中对数据查询结果进行排序的方法
Jul 17 Python
python:socket传输大文件示例
Jan 18 Python
Python中easy_install 和 pip 的安装及使用
Jun 05 Python
浅析Git版本控制器使用
Dec 10 Python
Python中装饰器高级用法详解
Dec 25 Python
Python实现可自定义大小的截屏功能
Jan 20 Python
Mac 使用python3的matplot画图不显示的解决
Nov 23 Python
安装多个版本的TensorFlow的方法步骤
Apr 21 Python
python连接mysql有哪些方法
Jun 24 Python
Python如何合并多个字典或映射
Jul 24 Python
python opencv检测直线 cv2.HoughLinesP的实现
Jun 18 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缓存技术的使用说明
2011/08/06 PHP
php通过array_merge()函数合并两个数组的方法
2015/03/18 PHP
如何使用PHP对网站验证码进行破解
2015/09/17 PHP
javascript编程起步(第四课)
2007/02/27 Javascript
JS/FLASH实现复制代码到剪贴板(兼容所有浏览器)
2013/05/27 Javascript
js螺旋动画效果的具体实例
2013/11/15 Javascript
JavaScript中property和attribute的区别详细介绍
2015/03/03 Javascript
JQuery限制复选框checkbox可选中个数的方法
2015/04/20 Javascript
javascript实现在网页任意处点左键弹出隐藏菜单的方法
2015/05/13 Javascript
理解javascript中的严格模式
2016/02/01 Javascript
js中获取jsp表单中radio类型的值简单实例
2016/08/15 Javascript
移动端日期插件Mobiscroll.js使用详解
2016/12/19 Javascript
jQuery插件HighCharts绘制2D带有Legend的饼图效果示例【附demo源码下载】
2017/03/10 Javascript
vue数字类型过滤器的示例代码
2017/09/07 Javascript
Node.js中使用mongoose操作mongodb数据库的方法
2017/09/12 Javascript
JS使用正则表达式获取小括号、中括号及花括号内容的方法示例
2018/06/01 Javascript
element-ui中的select下拉列表设置默认值方法
2018/08/24 Javascript
js获取url页面id,也就是最后的数字文件名
2020/09/25 Javascript
Node使用koa2实现一个简单JWT鉴权的方法
2021/01/26 Javascript
python 布尔操作实现代码
2013/03/23 Python
python2.7删除文件夹和删除文件代码实例
2013/12/18 Python
linux 下实现python多版本安装实践
2014/11/18 Python
Python数据结构之翻转链表
2017/02/25 Python
python批量修改文件编码格式的方法
2018/05/31 Python
PyQt5 对图片进行缩放的实例
2019/06/18 Python
django 中的聚合函数,分组函数,F 查询,Q查询
2019/07/25 Python
使用virtualenv创建Python环境及PyQT5环境配置的方法
2019/09/10 Python
使用Jupyter notebooks上传文件夹或大量数据到服务器
2020/04/14 Python
如何实现更换Jupyter Notebook内核Python版本
2020/05/18 Python
Python延迟绑定问题原理及解决方案
2020/08/04 Python
MAC平台基于Python Appium环境搭建过程图解
2020/08/13 Python
python判断变量是否为列表的方法
2020/09/17 Python
Lulu & Georgia官方网站:购买地毯、家具、抱枕、壁纸、床上用品等
2018/03/19 全球购物
求职自荐信
2013/12/14 职场文书
垃圾分类的活动方案
2014/08/15 职场文书
vue使用echarts实现折线图
2022/03/21 Vue.js