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 相关文章推荐
Flask入门教程实例:搭建一个静态博客
Mar 27 Python
Python中函数的参数定义和可变参数用法实例分析
Jun 04 Python
Python中max函数用法实例分析
Jul 17 Python
Django基于ORM操作数据库的方法详解
Mar 27 Python
TensorFlow 合并/连接数组的方法
Jul 27 Python
pip指定python位置安装软件包的方法
Jul 12 Python
python多进程并行代码实例
Sep 30 Python
Scrapy框架实现的登录网站操作示例
Feb 06 Python
Keras构建神经网络踩坑(解决model.predict预测值全为0.0的问题)
Jul 07 Python
Django-silk性能测试工具安装及使用解析
Nov 28 Python
Python之Sklearn使用入门教程
Feb 19 Python
Pytorch使用shuffle打乱数据的操作
May 20 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+Ajax异步通讯实现用户名邮箱验证是否已注册( 2种方法实现)
2011/12/28 PHP
php用户注册页面利用js进行表单验证具体实例
2013/10/17 PHP
php生成圆角图片的方法
2015/04/07 PHP
php输出图像的方法实例分析
2017/02/16 PHP
window.name代替cookie的实现代码
2010/11/28 Javascript
ASP.NET jQuery 实例6 (实现CheckBoxList成员全选或全取消)
2012/01/13 Javascript
javascript标签在页面中的位置探讨
2013/04/11 Javascript
js对象转json数组的简单实现案例
2014/02/28 Javascript
JavaScript中的数组操作介绍
2014/12/30 Javascript
JS实现网页游戏中滑块响应鼠标点击移动效果
2015/10/19 Javascript
深入浅析JavaScript中的scrollTop
2016/07/11 Javascript
jQuery插件easyUI实现通过JS显示Dialog的方法
2016/09/16 Javascript
JS获取html元素的标记名实现方法
2016/10/08 Javascript
js 转json格式的字符串为对象或数组(前后台)的方法
2016/11/02 Javascript
基于angular实现模拟微信小程序swiper组件
2017/06/11 Javascript
Vuejs中的watch实例详解(监听者)
2020/01/05 Javascript
vue video和vue-video-player实现视频铺满教程
2020/10/30 Javascript
es5 类与es6中class的区别小结
2020/11/09 Javascript
一张图带我们入门Python基础教程
2017/02/05 Python
无法使用pip命令安装python第三方库的原因及解决方法
2018/06/12 Python
Selenium(Python web测试工具)基本用法详解
2018/08/10 Python
python 获取毫秒数,计算调用时长的方法
2019/02/20 Python
Pycharm如何打断点的方法步骤
2019/06/13 Python
解决Django加载静态资源失败的问题
2019/07/28 Python
python+rsync精确同步指定格式文件
2019/08/29 Python
wxPython实现分隔窗口
2019/11/19 Python
Django restframework 框架认证、权限、限流用法示例
2019/12/21 Python
Python嵌入C/C++进行开发详解
2020/06/09 Python
Django解决frame拒绝问题的方法
2020/12/18 Python
从Pytorch模型pth文件中读取参数成numpy矩阵的操作
2021/03/04 Python
医药销售求职信范文
2014/02/01 职场文书
2014年保洁工作总结
2014/11/24 职场文书
入党培养人考察意见
2015/06/08 职场文书
如何写好活动总结
2019/06/21 职场文书
详解GaussDB for MySQL性能优化
2021/05/18 MySQL
我收到了德劲DE1107
2022/04/05 无线电