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自动化工具日志查询分析脚本代码实现
Nov 26 Python
在Django的模型中添加自定义方法的示例
Jul 21 Python
Python中的Descriptor描述符学习教程
Jun 02 Python
在Python中定义一个常量的方法
Nov 10 Python
python实现浪漫的烟花秀
Jan 30 Python
Python读取stdin方法实例
May 24 Python
python安装requests库的实例代码
Jun 25 Python
Python 正则表达式 re.match/re.search/re.sub的使用解析
Jul 22 Python
用python生成与调用cntk模型代码演示方法
Aug 26 Python
Python通过两个dataframe用for循环求笛卡尔积
Apr 29 Python
Python文件操作及内置函数flush原理解析
Oct 13 Python
用Python将库打包发布到pypi
Apr 13 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
分享8个最佳的代码片段在线测试网站
2013/06/29 PHP
PHP正则替换函数preg_replace和preg_replace_callback使用总结
2014/09/22 PHP
详解PHP序列化反序列化的方法
2015/10/27 PHP
简单了解PHP编程中数组的指针的使用
2015/11/30 PHP
PHP7 新增功能
2021/03/09 PHP
从URL中提取参数与将对象转换为URL查询参数的实现代码
2012/01/12 Javascript
Eclipse去除js(JavaScript)验证错误
2014/02/11 Javascript
使用jQuery设置disabled属性与移除disabled属性
2014/08/21 Javascript
js控制网页前进和后退的方法
2015/06/08 Javascript
jquery简单实现幻灯片的方法
2015/08/03 Javascript
jquery实现一个简单的表单验证实例
2016/03/30 Javascript
js阻止默认浏览器行为与冒泡行为的实现代码
2016/05/15 Javascript
浅谈jquery中的each方法$.each、this.each、$.fn.each
2016/06/23 Javascript
JavaScript设计模式之单体模式全面解析
2016/09/09 Javascript
微信小程序开发之选项卡(窗口底部TabBar)页面切换
2017/04/12 Javascript
JavaScript模拟文件拖选框样式v1.0的实例
2017/08/04 Javascript
JavaScript使用Ajax上传文件的示例代码
2017/08/10 Javascript
Vue仿手机qq的实例代码(demo)
2017/09/08 Javascript
JS大坑之19位数的Number型精度丢失问题详解
2019/04/22 Javascript
js图片无缝滚动插件使用详解
2020/05/26 Javascript
微信小程序返回箭头跳转到指定页面实例解析
2019/10/08 Javascript
p5.js临摹动态图形实现方法详解
2019/10/23 Javascript
OpenLayers3实现图层控件功能
2020/09/25 Javascript
使用typescript快速开发一个cli的实现示例
2020/12/09 Javascript
python web框架学习笔记
2016/05/03 Python
django url到views参数传递的实例
2019/07/19 Python
使用keras实现Precise, Recall, F1-socre方式
2020/06/15 Python
Python logging模块异步线程写日志实现过程解析
2020/06/30 Python
用python制作个视频下载器
2021/02/01 Python
介绍一下Java中的Class类
2015/04/10 面试题
机械系毕业生求职信
2014/05/28 职场文书
一份教室追逐打闹的检讨书
2014/09/27 职场文书
银行开户授权委托书格式
2014/10/10 职场文书
灵魂歌王观后感
2015/06/17 职场文书
财务年终工作总结大全
2019/06/20 职场文书
Python中字符串对象语法分享
2022/02/24 Python