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 相关文章推荐
在Django的视图(View)外使用Session的方法
Jul 23 Python
Python批量修改文本文件内容的方法
Apr 29 Python
Python之Scrapy爬虫框架安装及简单使用详解
Dec 22 Python
python实现二叉查找树实例代码
Feb 08 Python
详解Django项目中模板标签及模板的继承与引用(网站中快速布置广告)
Mar 27 Python
python粘包问题及socket套接字编程详解
Jun 29 Python
用sqlalchemy构建Django连接池的实例
Aug 29 Python
使用Python为中秋节绘制一块美味的月饼
Sep 11 Python
python3 tkinter实现添加图片和文本
Nov 26 Python
Python列表list操作相关知识小结
Jan 29 Python
pip/anaconda修改镜像源,加快python模块安装速度的操作
Mar 04 Python
python人工智能human learn绘图可创建机器学习模型
Nov 23 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实现按文件名搜索文件的远程文件查找器
2014/05/10 PHP
用函数式编程技术编写优美的 JavaScript_ibm
2008/05/16 Javascript
javascript 模拟JQuery的Ready方法实现并出现的问题
2009/12/06 Javascript
javascript instanceof 内部机制探析
2010/10/15 Javascript
Javascript中arguments用法实例分析
2015/06/13 Javascript
jQuery获取页面及个元素高度、宽度的总结——超实用
2015/07/28 Javascript
基于jQuery Circlr插件实现产品图片360度旋转
2015/09/20 Javascript
JS实现双击屏幕滚动效果代码
2015/10/28 Javascript
JS实现经典的中国地区三级联动下拉菜单功能实例【测试可用】
2017/06/06 Javascript
Angular 4.x+Ionic3踩坑之Ionic 3.x界面传值详解
2018/03/13 Javascript
[01:00:44]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#1COL VS Alliance第三局
2016/03/04 DOTA
[36:05]完美世界DOTA2联赛循环赛 Forest vs DM 第一场 11.06
2020/11/06 DOTA
Python编程中的文件操作攻略
2015/10/16 Python
python使用paramiko实现远程拷贝文件的方法
2016/04/18 Python
使用python3.5仿微软记事本notepad
2016/06/15 Python
python实现将一个数组逆序输出的方法
2018/06/25 Python
Scrapy框架爬取Boss直聘网Python职位信息的源码
2019/02/22 Python
详解Python传入参数的几种方法
2019/05/16 Python
在交互式环境中执行Python程序过程详解
2019/07/12 Python
安装多个版本的TensorFlow的方法步骤
2020/04/21 Python
详解Anaconda安装tensorflow报错问题解决方法
2020/11/01 Python
Python实现Word文档转换Markdown的示例
2020/12/22 Python
HTML5 Canvas绘制文本及图片的基础教程
2016/03/14 HTML / CSS
美团网旗下网上订餐平台:美团外卖
2020/03/05 全球购物
C++:memset ,memcpy和strcpy的根本区别
2013/04/27 面试题
AJAX的优缺点都有什么
2015/08/18 面试题
什么是ESB?请介绍一下ESB?
2015/05/27 面试题
中英双版中文教师求职信
2013/10/27 职场文书
大众服装店创业计划书范文
2014/01/01 职场文书
给同学的道歉信
2014/01/16 职场文书
社区庆中秋节活动方案
2014/02/07 职场文书
高三毕业评语
2014/12/31 职场文书
档案工作个人总结
2015/03/03 职场文书
致短跑运动员加油稿
2015/07/21 职场文书
2016年大学生社区服务活动总结
2016/04/06 职场文书
一文搞懂Python Sklearn库使用
2021/08/23 Python