python并发编程:阻塞IO

阻塞IO(blocking  IO)

在Linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样:

  当用户进程调用了recvfrom这个系统调用,kernel就开始了IO的第一个阶段:准备数据。对于network io来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的udp包),这个时候kernel就要等待足够的数据到来

1

2

而在用户进程这边,整个进程会被阻塞,当kernel一直等到数据准备好了,它就会将数据从kernel中拷贝到用户内存

然后kernel返回结果,用户进程才解除block的状态,重新运行起来

  所以,blocking IO的特点就是在IO执行的两个阶段(等待数据和拷贝数据两个阶段)都被block了

1

2

3

4

5

6

7

8

9

10

几乎所有的程序员第一次接触到的网络编程都是从listen(),send(),recv()等接口开

始的,使用这些接口可以很方便的构建服务器/客户机的模型。然而大部分的socket接口都是

阻塞型的。如下图

ps:

所谓阻塞型接口是指系统调用(一般是IO接口)不返回调用结果并让当前线程一直阻塞

只有当该系统调用获得结果或者超时出错时才返回。

  

实际上,除非特别指定,几乎所有的IO接口(包括socket接口)都是阻塞型的。这给网络编程带来了一个很大的问题。如在调用recv(1024)的同时,线程将被阻塞,在此期间,线程将无法执行任何运算或响应任何的网络请求。

一个简单的解决方案:

1

在服务端使用多线程(或多进程)。多线程(或多进程)的目的是让每个连接都拥有独立的线程(或进程),这样任何一个连接的阻塞都不会影响其他的连接。

  该方案的问题是:

1

开启多进程或多线程的方式,在遇到同时响应成百上千的连接请求,则无论多线程还是多进程都会严重占据系统资源,降低系统对外界响应效率,而且线程与进程本身也更容易进入假死状态

  改进方案:

1

2

很多程序员可能会考虑使用“线程池”或“连接池”。“线程池”旨在减少创建和销毁线程的频率,其维持一定合理数量的线程,并让空闲的线程重新承担新的执行任务。“连接池”维持连接的缓存池,尽量重用已有的连接,减少创建和关闭连接的频率。这两种技术都可以很好的降低系统开销,都被广泛应用很多

大型系统,如websphere、tomcat和各种数据库等

  改进后方案其实也存在着问题:

1

2

3

“线程池”和“连接池”技术也只是在一定程度上缓解了频繁调用IO接口带来的资源占用。而且“池”始终尤其上限,当请求大大超过上限时,“池”构成的系统对外界的响应并不比没有池

的时候效果好多少。

所以使用“池”必须考虑其面临的响应规模,并根据规模调整“池”的大小

  对应上例中的所面临的可能同时出现的上千甚至上万次的客户端请求,“线程池”或“连接池”或许可以缓解部分压力,但是不能解决所有问题。总之,多线程模型可以方便高效的解决小规模的服务请求,但面对大规模的服务请求,多线程模型也会遇到瓶颈,可以用非阻塞接口来尝试解决这个问题。

练习:

服务端:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

from socket import *

from threading import Thread

def communicate(conn):

    while True:

        try:

            data = conn.recv(1024)

            if not data:

                break

            conn.send(data.upper())

        except ConnectionResetError:

            break

    conn.close()

server = socket(AF_INET, SOCK_STREAM)

server.bind(('127.0.0.1'8080))

server.listen(5)

while True:

    print('starting...')

    conn,addr = server.accept()

    print(addr)

    = Thread(target=communicate, args=(conn,))

    t.start()

server.close()

  客户端:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

from socket import *

client = socket(AF_INET, SOCK_STREAM)

client.connect(('127.0.0.1'8080))

while True:

    msg = input("请输入数据:").strip()

    if not msg:

        continue

    client.send(msg.encode('utf-8'))

    data = client.recv(1024)

    print(data.decode('utf-8'))

client.close()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/437246.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣513 找树左下角的值 Java版本

文章目录 题目描述解题思路代码 题目描述 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1 示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7 提示: 二…

Openwrt(IstoreOS)安装iventoy

背景 目前家里有两台不用的旧主机,平时没事在家里折腾这两台机器。经常换装各种系统。最早是将镜像刷入u盘作为启动盘,这样需要重复装系统就特别麻烦。后来用了ventoy以后一个U盘可以放多个系统镜像,还能做口袋系统(SystemToGo&a…

MedSAM 项目排坑记录

MedSAM 项目排坑记录 任务排坑过程配置python环境测试构建docker模型训练数据预处理 单GPU训练最后推理 任务 做一个课程大作业,需要进行CVPR2024年医疗影像分割赛题的打榜(CVPR 2024: SEGMENT ANYTHING IN MEDICAL IMAGES ON LAPTOP)。看到…

Flink实时数仓同步:切片表实战详解

一、背景 在大数据领域,初始阶段业务数据通常被存储于关系型数据库,如MySQL。然而,为满足日常分析和报表等需求,大数据平台采用多种同步方式,以适应这些业务数据的不同存储需求。 一项常见需求是,业务使用…

分布式事务-Seata

分布式事务:在分布式系统下,一个业务跨越多个服务或者数据源,每个服务都是一个分支事务,要保证所有分支事务最终一致,这样的事务就是分布式事务、 事务ACID原则 原子性:事务中的所有操作,要么全部成功,要么全部失败 一致性:要保…

go语言基础 -- 单元测试

go语言testing框架说明 go语言有自己的测试框架,封装在testing包中。 我们编写的测试案例通常都写在xxx_test.go文件中,比如我们写了个calc.go,对里面的函数进行测试,通常会写一个calc_test.go;testing框架会将_test.go结尾的文件引入;testing框架会在自己的main方法中执…

太阳能光伏电池的simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 光伏电池的基本结构 4.2 光伏电池的工作原理 5.完整工程文件 1.课题概述 太阳能光伏电池的simulink建模与仿真.分析不同光照温度,光照强度下的光伏电池的U-I特性曲线以及P-V特性曲线。 …

车辆伤害VR安全教育培训复用性强

VR工地伤害虚拟体验是一种新兴的培训方式,它利用虚拟现实技术为参与者提供身临其境的体验。与传统的培训方式相比,VR工地伤害虚拟体验具有许多优势。 首先,VR工地伤害虚拟体验能够模拟真实的工作环境和事故场景,让参与者在安全的环…

C++ 路径问题

目录 例1 例2 例3 例4 例5 例6 例1 62. 不同路径 1.初始化 2.当前位置的条数,就是上面位置的条数 ,加上其左边位置的条数,dp[i][j] dp[i - 1][j] dp[i][j - 1]; 参考代码 class Solution { public:int uniquePaths(int m, int n) …

静态时序分析:典型与非典型时序路径的约束详解(一)

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 时序路径是静态时序分析中的一个重要概念,了解时序路径能帮助设计者更好地编写SDC脚本,本文旨在详细介绍时序路径相关内容。 首先给出时序…

Git误操作补救错失:恢复误删的本地分支、将某个提交从一个分支复制到另一个分支

一、恢复误删的本地分支 作为一枚强迫症,没用的分支总是喜欢及时删删删删掉删掉统统删掉,结果今天发现有些分支还是应该保留。 比如,①前段时间切了个分支用来专门做图表,但因为需求还没有最终确定,已经上线了测试服而…

计网《一》|互联网结构发展史|标准化工作|互联网组成|性能指标|计算机网络体系结构

计网《一》| 概述 计算机网络在信息时代的作用什么是互联网呢?互联网有什么用呢?为什么互联网能为用户提供许多服务 互联网基础结构发展的三个阶段第一个阶段:第二阶段:第三个阶段: 互联网标准化的工作互联网的组成边缘…

Observer 模式

文章目录 💡问题引入💡概念💡例子💡总结 💡问题引入 假设有一个在线商店系统,用户可以订阅商品的库存通知。当某个商品的库存数量发生变化时,系统会自动发送通知给所有订阅了该商品的用户。设计…

Android 13 WMS-动画流程

动画的类型如下 IntDef(flag true, prefix { "ANIMATION_TYPE_" }, value {ANIMATION_TYPE_NONE,ANIMATION_TYPE_APP_TRANSITION,ANIMATION_TYPE_SCREEN_ROTATION,ANIMATION_TYPE_DIMMER,ANIMATION_TYPE_RECENTS,ANIMATION_TYPE_WINDOW_ANIMATION,ANIMATION_TYPE_…

CentOS7.9基于Apache2.4+Php7.4+Mysql8.0架构部署Zabbix6.0LTS 亲测验证完美通过方案

前言: Zabbix 由 Alexei Vladishev 创建,目前由 Zabbix SIA 主导开发和支持。 Zabbix 是一个企业级的开源分布式监控解决方案。 Zabbix 是一款监控网络的众多参数以及服务器、虚拟机、应用程序、服务、数据库、网站、云等的健康和完整性的软件。 Zabbix 使用灵活的通知机制,…

云计算项目八:Harbor

部署企业私有镜像仓库Harbor 私有镜像仓库有许多优点: 节省网络带宽,针对于每个镜像不用每个人都去中央仓库上面去下载,只需要从私有仓库中下载即可提供镜像资源利用,针对于公司内部使用的镜像,推送到本地私有仓库中…

华硕AMD主板开启TPM2.0支持

目录 配置问题设置开启 Firmware TPM开启 Security Device Support保存设置 检查 配置 主板:TUF Gaming B550m-e Wifi   BIOS: 3402 问题 今天更新Win11,告诉我不支持 TPM 2.0,导致更新失败。   网上搜这个问题,基本只提供了…

selenium中ChromeDriver配置,一把过,并且教你伪装

最近正值毕业季,我之前不是写了个问卷星代码嘛,昨晚上有人凌晨1点加我,问我相关内容。 由于我之前C盘重装了一下,导致我很多东西空有其表,实际不能用,借此机会,向大家编写ChromeDriver配置&…

江苏某机场多座智慧公厕上线,黑科技满满打造标杆性机场智慧卫生间

在现代社会,智慧科技正在各个领域中得到广泛应用,机场也不例外。智慧机场是信息化程度、建设标准、功能要求最高的领域,智慧卫生间的建设要求同样是业界的最高标准。智慧公厕源头厂家广州中期科技有限公司,已经建设了浙江某机场、…

SICP解读指南:深度阅读 “计算机领域三巨头” 之一(文末送书)

🌈个人主页:聆风吟_ 🔥系列专栏:Linux实践室、网络奇遇记 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. 书籍介绍1.1 SICP侧重点1.2 SICP章节介绍 二. 书籍推荐2.1 书籍介绍2.2 推…