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中类的定义、继承及使用对象实例详解
Apr 30 Python
python实现获取Ip归属地等信息
Aug 27 Python
itchat和matplotlib的结合使用爬取微信信息的实例
Aug 25 Python
python利用正则表达式搜索单词示例代码
Sep 24 Python
numpy自动生成数组详解
Dec 15 Python
python人民币小写转大写辅助工具
Jun 20 Python
TensorBoard 计算图的可视化实现
Feb 15 Python
浅谈matplotlib.pyplot与axes的关系
Mar 06 Python
Python如何基于Tesseract实现识别文字功能
Jun 05 Python
Python matplotlib图例放在外侧保存时显示不完整问题解决
Jul 28 Python
python使用建议与技巧分享(一)
Aug 17 Python
Python实现哲学家就餐问题实例代码
Nov 09 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 mysql 判断update之后是否更新了的方法
2012/01/10 PHP
PHP中对缓冲区的控制实现代码
2013/09/29 PHP
php隐藏实际地址的文件下载方法
2015/04/18 PHP
PHP微信网页授权的配置文件操作分析
2019/05/29 PHP
js实现页面转发功能示例代码
2013/08/05 Javascript
NodeJS与Mysql的交互示例代码
2013/08/18 NodeJs
JavaScript instanceof 的使用方法示例介绍
2013/10/23 Javascript
jQuery探测位置的提示弹窗(toolTip box)详细解析
2013/11/14 Javascript
JS 使用for循环遍历子节点查找元素
2014/09/06 Javascript
node.js中的fs.fstatSync方法使用说明
2014/12/15 Javascript
js判断文本框剩余可输入字数的方法
2015/02/04 Javascript
纯JS单页面赛车游戏制作代码分享
2017/03/03 Javascript
Webpack打包慢问题的完美解决方法
2017/03/16 Javascript
vue实现全选、反选功能
2020/11/17 Javascript
基于vue.js 2.x的虚拟滚动条的示例代码
2018/01/23 Javascript
react native 仿微信聊天室实例代码
2019/09/17 Javascript
JS判断数组四种实现方法详解
2020/06/29 Javascript
Vue-router编程式导航的两种实现代码
2021/03/04 Vue.js
python如何为被装饰的函数保留元数据
2018/03/21 Python
Pycharm新手教程(只需要看这篇就够了)
2019/06/18 Python
python字符串替换第一个字符串的方法
2019/06/26 Python
python每5分钟从kafka中提取数据的例子
2019/12/23 Python
kafka监控获取指定topic的消息总量示例
2019/12/23 Python
Python object类中的特殊方法代码讲解
2020/03/06 Python
pycharm通过anaconda安装pyqt5的教程
2020/03/24 Python
在Keras中CNN联合LSTM进行分类实例
2020/06/29 Python
Calzedonia美国官网:意大利风格袜子、打底裤和沙滩装
2018/07/19 全球购物
Yves Rocher伊夫·黎雪美国官网:法国始创植物美肌1959
2019/01/09 全球购物
医学专业自荐信
2014/06/14 职场文书
房地产端午节活动方案
2014/08/24 职场文书
2014年计生工作总结
2014/11/21 职场文书
2014年信息中心工作总结
2014/12/17 职场文书
团委工作总结2015
2015/04/02 职场文书
建党伟业观后感
2015/06/01 职场文书
诗词赏析-(浣溪沙)
2019/08/13 职场文书
Mysql存储过程、触发器、事件调度器使用入门指南
2022/01/22 MySQL