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 re模块介绍
Nov 30 Python
安装dbus-python的简要教程
May 05 Python
Unicode和Python的中文处理
Mar 19 Python
python opencv3实现人脸识别(windows)
May 25 Python
django 在原有表格添加或删除字段的实例
May 27 Python
python3.4实现邮件发送功能
May 28 Python
django框架使用方法详解
Jul 18 Python
Django User 模块之 AbstractUser 扩展详解
Mar 11 Python
自定义实现 PyQt5 下拉复选框 ComboCheckBox的完整代码
Mar 30 Python
Pycharm github配置实现过程图解
Oct 13 Python
python爬虫工具例举说明
Nov 30 Python
python中uuid模块实例浅析
Dec 29 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单态模式简单用法示例
2016/11/16 PHP
php字符串函数 str类常见用法示例
2020/05/15 PHP
js实现ASP分页函数 HTML分页函数
2006/09/22 Javascript
动态改变textbox的宽高的js
2006/10/26 Javascript
javascript 常用功能总结
2012/03/18 Javascript
js中parseFloat(参数1,参数2)定义和用法及注意事项
2013/01/27 Javascript
详解JavaScript函数绑定
2013/08/18 Javascript
js防止表单重复提交的两种方法
2013/09/30 Javascript
jQuery简单实现隐藏以及显示特效
2015/02/26 Javascript
jQuery删除一个元素后淡出效果展示删除过程的方法
2015/03/18 Javascript
理解javascript中DOM事件
2015/12/25 Javascript
JavaScript实现页面跳转的方式汇总
2016/05/16 Javascript
jquery实现(textarea)placeholder自动换行
2016/12/22 Javascript
js通过指定下标或指定元素进行删除数组的实例
2017/01/12 Javascript
js实现图片粘贴上传到服务器并展示的实例
2017/11/08 Javascript
详解javascript常用工具类的封装
2018/01/30 Javascript
jQuery使用动画队列自定义动画操作示例
2018/06/16 jQuery
Vue 列表上下过渡效果的实例代码
2019/06/25 Javascript
解决在Vue中使用axios用form表单出现的问题
2019/10/30 Javascript
NodeJS实现一个聊天室功能
2019/11/25 NodeJs
vue 点击其他区域关闭自定义div操作
2020/07/17 Javascript
[01:33]一分钟玩转DOTA2第三弹:DOTA2&DotA快捷操作大对比
2014/06/04 DOTA
python对list中的每个元素进行某种操作的方法
2018/06/29 Python
如何使用Python自动控制windows桌面
2019/07/11 Python
关于PyTorch源码解读之torchvision.models
2019/08/17 Python
python打印n位数“水仙花数”(实例代码)
2019/12/25 Python
TensorFlow实现自定义Op方式
2020/02/04 Python
解决Python数据可视化中文部分显示方块问题
2020/05/16 Python
html5 canvas 使用示例
2010/10/22 HTML / CSS
韩国休闲女装品牌网站:ANAIS
2016/08/24 全球购物
投标保密承诺书
2014/05/19 职场文书
学校安全防火方案
2014/06/07 职场文书
“四风”问题整改措施和努力方向
2014/09/20 职场文书
工作自我评价范文
2015/03/05 职场文书
python开发人人对战的五子棋小游戏
2022/05/02 Python
hive数据仓库新增字段方法
2022/06/25 数据库