Linux下I/O模型介绍

服务器基础:聊聊Linux中的5种I/O模型----面试题目2019年 1 概念说明 在进行解释之前,首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 IO 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用... 阅读详情

阻塞I/O

阻塞 I/O 模型是最原始的模型,进程一旦执行某个函数调用,进程就进入休眠状态(Sleeping)。比如平时FIFO管道的 read,还有基于TCP的流socket的 read 调用,进程一旦进行系统函数的调用,会从用户态切入内核态,内核会进行系统调用 read ,这时候如果对应的流(管道,socket都算)还没准备写入数据,那么 read 函数就会阻塞,从而导致进程挂起。直到数据来了,内核才会把数据拷贝从内核的缓冲区到进程用户的缓冲区。这时候 read 函数才能返回,进程才能向下走,继续下面的处理。整个过程是串行的,必须一步一步来。

block

#!/usr/bin/python
 
'''
    tcp socket server
'''
 
import sys
import socket
 
HOST = ''
PORT = 9243
DATA_BUFFER = 4096
 
# create a TCP socket
try :
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print 'Socket created'
except socket.error, msg :
    print 'Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()
 
# Bind socket to local host and port
try:
    s.bind((HOST, PORT))
except socket.error , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()
 
s.listen(5)         # allow 5 simultaneous
 
while True:
    # wait for next client to connect
    connection, address = s.accept()        # blocking
    while True:
        data = connection.recv(DATA_BUFFER) # blocking
        if data:
            print data
        else:
            break
    connection.close()                      # close socket

上面的代码就是一个 server 端阻塞的调用,accept阻塞在三次握手之前,recv阻塞在网卡获取数据,产生中断,内核拷贝数据到用户进程之前。

非阻塞I/O

进程调用recvfrom,这时候进程会不断去问内核数据是否有数据,这也就是所望的 polling 轮询模式,这会导致 cpu 大量的空转。

poll

while True:
        # wait for next client to connect
        connection, address = s.accept()                # connection is a new socket
        while True:
                print "waiting for data"
                data = connection.recvfrom(DATA_BUFFER) # receive up to 1K bytes
        connection.close()

上面的代码一旦socket连接好后,进程就开始不断轮询,不断打印”waiting for data”,虽然进程是不 sleep 了,但是其实和 sleep 没啥区别。而去还不断进行系统调用,导致 cpu 空转,这种模型在正常情况下相比阻塞模型没有任何优点。这就叫非阻塞“忙”轮询。

Select模型

在阻塞I/O模式下,一个进程或线程只能处理一个流的I/O事件。如果想要同时处理多个流,要么多进程(fork),要么多线程(pthread_create),很不幸这两种方法效率都不高。为了避免CPU空转,可以引进一个代理(一开始有一位叫做select的代理,后来又有一位叫做poll的代理,不过两者的本质是一样的)。这个代理比较厉害,可以同时观察许多流的I/O事件,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞态中醒来,于是我们的程序就会轮询一遍所有的流(于是我们可以把“忙”字去掉了)

select

当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回套接字可读这个条件,我们调用recvfrom把所读数据报拷贝到应用程序进程缓冲区。

while True:
    print "Select blocking..."
    infds,outfds,errfds = select.select([s,],[],[],time_out)
    if len(infds) > 0 :
        # wait for next client to connect
        for sock in infds:
            connection, address = sock.accept()     # connection is a new socket
            print "Connected successfully !"
            connection.close()

和阻塞相比,select也没啥优势,唯一优势在于它可以同时处理多个感兴趣的描述符。

附:select函数用法

select.select(rlist,wlist, xlist[, timeout])

This is a straightforward interface to the Unix select() system call. The first three arguments are sequences of ‘waitable objects’: either integers representing file descriptors or objects with a parameterless method named fileno() returning such an integer:

rlist: wait until ready for reading
wlist: wait until ready for writing
xlist: wait for an “exceptional condition” (see the manual page for what your system considers such a condition)
Empty sequences are allowed, but acceptance of three empty sequences is platform-dependent. (It is known to work on Unix but not on Windows.) The optional timeout argument specifies a time-out as a floating point number in seconds. When the timeout argument is omitted the function blocks until at least one file descriptor is ready. A time-out value of zero specifies a poll and never blocks.

The return value is a triple of lists of objects that are ready: subsets of the first three arguments. When the time-out is reached without a file descriptor becoming ready, three empty lists are returned.

Among the acceptable object types in the sequences are Python file objects (e.g. sys.stdin, or objects returned by open() or os.popen()), socket objects returned by socket.socket(). You may also define a wrapper class yourself, as long as it has an appropriate fileno() method (that really returns a file descriptor, not just a random integer).

I/O模型 1 概念说明 在进行解释之前,首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 IO 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核(kernel),保证内核的安全,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。针对linux操作系 阅读详情

相关推荐

DC-DC电源PCB布局实战:从EMI优化到热管理

本文深入探讨了DC-DC电源PCB布局的核心实战技巧。文章从分析电流环路入手,强调通过优化“黄金三角”布局以最小化环路面积,从而有效抑制EMI并提升效率。详细阐述了功率器件摆放、地线分割、敏感信号布线、电感下方铺铜策略以及热管理设计等关键步骤,为工程师提供了一套从理论到实践的完整布局指南。

z5a6b的博客 720

Linux下常见I/O模型及其相关基础知识

自从接触Linux服务器开发到现在,对于阻塞、非阻塞、同步、异步这些概念其实还是感觉挺模糊的,查了很多资料,看了很多博客和文章,现在从个人理解的角度来总结一下这些概念的区别,既方便自己的复习,也希望可以给看到这篇博客的伙伴们一个相对正确的指引。 I/O复用是什么 I/O多路复用就是一种使得程序可以同时监听多个文件描述符的技术,能够提高程序的性能。其中的I/O是指socket对读写缓冲区(内存)的读写操作,不是简单意义上的cin和cout。在Linux下能够实现I/O多路复用的系统调用方法主要有:select

bulangman277的博客 1460

gd32 spi 发送&中断接收例程

【代码】gd32 spi 发送&中断接收例程。

weixin_43026921的博客 1653

1.Linux网络I/O模型概述

Linux网络I/O模型概述      Linux内核将所有的外部设备都看成一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令,返回一个file descriptor(fd,文件描述符)。       而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符),描述符就是一个数字,它指向内核中的一个结构体(文件路径,数据区等属性)。       UNIX提供...

写后端的小学生 1355

DETRs with Collaborative Hybrid Assignments Training论文阅读与代码

在这篇论文中,作者观察到在DETR中将过少的 Query 分配为正样本,采用一对一的集合匹配,会导致对编码器输出的监督稀疏,严重损害编码器的区分特征学习,反之亦然,也会影响解码器中的注意力学习。为了缓解这个问题,作者提出了一种新颖的协同混合分配训练方案,名为Co-DETR,以从多样的标签分配方式中学习更高效、更有效的基于DETR的检测器。这种新的训练方案可以通过训练多个并行辅助 Head ,以一对多的标签分配方式(如ATSS和Faster RCNN)进行监督,轻松增强端到端检测器中编码器的学习能力。

qingjing0413的博客 1154

8.Python基础语法(五)续【光说不练假把式,上题】

Python基础语法(二) 有关于Python循环语句的几道实操,让大家理解知识点更深更透彻~

孤寒者的博客 2万+

Linux I/O模型简介

1、基本概念 在进行网络编程时,我们常常见到同步(Sync)、异步(Async),阻塞(Block)、非阻塞(Unblock)四种调用方式。 同步:调用一个功能,该功能没有结束前,一直等待。 异步:调用一个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知)。 阻塞:调用函数,函数没有接收完数据或者没有得到结果之前,不会返回。 非阻塞:调用我函数,函数立即返回,通过select通...

u012606648的博客 282

FOC 转子初始位置检测(图文详解)

什么是转子的初始位置? 其实转子的初始位置是不确定的,但是在电机启动的时候,我们需要得到电角度,这样才可以进行矢量控制;所以,这里将转子与A轴重合作为初始位置,此时电角度也恰好为零,具体如下图所示; ) 至于原理下面会详细分析,这样在转子到初始位置后,也可以得到准确的电角度,就可以实现磁场和转子的同步转动。 如何让转子运行到初始位置? 其实这是一个很简单的问题,在这里我将它放大了,简单地分析了一...

一名热爱技术的工程师的博客。分享技术干货,记录美好生活。永远相信美好的事情即将发生。 2万+

Netty入门笔记-Linux网络I/O模型介绍

在之前的博客中并没有将关于Netty的知识系统的总结起来。从这篇博客开始就将关于Netty的有关知识点总结起来顺便提升自己的分析问题的能力,通过博客分享的形式将学习的知识点形成体系,希望也可以帮助大家一起学习提高。 引言   在之前老版本的JDK中,对于IO性能问题支持的并不是太好,很多的情况下并不能正常的完成对于IO性能的要求。对于IO的操作问题主要体现在以下的几个方面。 1、没有很好的数...

初学者 2782

勇闯dify v1.0.0之设置模型供应商。解决:Reached maximum retries (3) for URL https://marketplace.dify.ai/

朋友们,大家好,今天带大家来勇闯dify v1.0.0。为什么叫勇闯呢?我就这么说吧,本来我昨天就想带大家勇闯v1.0.0的。但是dify的marketplace访问不了。公司的网和手机热点都试了,就是访问不了。我们连个模型都没有,还勇闯个球啊,对吧,就搁置了。今天,我赶紧看看这个marketplace好了没。一看,可以了。赶紧写下这篇博客,帮助同志们走出困境。

xiezhipu的博客 4616

C# Socket通信从入门到精通(14)——多个异步UDP客户端C#代码实现(史上最全)

本文详细介绍了Socket通信中多个异步Udp客户端功能的实现、介绍如何使用多个客户端与多个服务器进行数据的交互,包含连接服务器、断开服务器、发送数据、读取数据、C#代码实现,由高级工程师多年经验总结而成,绝对干货!

qq_34059233的博客 1982

Netty快速入门(01)Linux I/O模型介绍

Netty简述 *Netty是一个高性能的网络编程框架。* 上面提到了几个关键的字眼,高性能,网络编程,框架。这些概括Netty的本质。 Netty是一个NIO客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化并简化了TCP和UDP套接字服务器等网络编程。 “快速简便”并不意味着最终的应用程序会受到可维护性或性能问题的影响。Netty经过精心设计,具有丰富...

Blues的专栏 1047

书旗app字符串加密分析

本文案例是对书旗app搜索接口的请求密文进行分析和逆向。

李玺 3156

Linux I/O模型介绍

linux IO流程 Linux IO流程: 第一阶段 等待数据准备好(Waiting for the data to be ready) 第二阶段 从内核向进程复制数据(Copying the data from the kernel to the process) 有两次数据拷贝 第一次 DMA从磁盘上读取数据拷贝到内核空间 第二次 数据从内核空间拷贝到用户空间 I/O模型划...

weixin_45804540的博客 167

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Linux四种I/O模型简单介绍下

在Linux下主要有四种I/O模型:

m0_59327517的博客 143

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

5种Linux网络I/O模型介绍

本文介绍了Linux系统里的五种I/O模型的特点、工作流程等,此外还介绍了他们的划分依据以及系统调用、用户空间等概念。

第四空间 242

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Netty 快速入门(01)Linux I/O模型介绍

Netty简述 Netty是一个高性能的网络编程框架 上面提到的几个关键的字眼,高性能,网络编程,框架。这些概括Netty的本质。 Netty是一个NIO客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大的简化并TCP和UDP套接字服务器等网络编程。 “快速简便”并不意味着最终的应用程序会受到可维护性或性能问题的影响。Netty经过精心设计,具有丰富的协议,如...

weixin_41932611的博客 198

Linux I/O复用中select poll epoll模型的介绍及其优缺点的比较

**关于I/O多路复用:** I/O多路复用(又被称为“事件驱动”),首先要理解的是,操作系统为你提供了一个功能,当你的某个socket可读或者可写的时候,它可以给你一个通知。这样当配合非阻塞的socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据而不做纯返回-1和EAGAIN的无用功。写操作类似。操作系统的这个功能通过select/pol

Chengzi_comm的专栏 1万+

linux下的 I/O 模型,同步/异步,阻塞/非阻塞介绍

同步/异步,阻塞/非阻塞 一提到网络编程中的 I/O 模型,总会涉及到这几个概念,但是这几个名词又容易混淆,于是我想总结一下。 我们先看一下在《UNIX网络编程:卷一》中讲到的5中 UNIX 下的 I/O 模型,分别是 阻塞式 I/O 非阻塞式 I/O I/O 复用 信号驱动式 I/O 异步 I/O 五种 I/O 模型 阻塞式 I/O 模型 默认情况下,所有的套接字都是阻塞的。

悠然见南山的博客 584

## Linux面试问题汇总----Linux的I/O模型介绍以及同步异步阻塞非阻塞的区别

## Linux面试问题汇总 Linux的I/O模型介绍以及同步异步阻塞非阻塞的区别(超级重要) 一般来说,Linux下系统IO主要就是通过以下几个函数open(),close(),read(),write(),send(),recv(),lseek(),今天就以recv()为例来介绍下IO模型中的...

weixin_41563161的博客 1877

浅析Linux系统I/O模型

在操作系统中,I/O类操作是相对慢速的,应用发起一个I/O操作,需要等待I/O资源就绪后,才能继续后面的处理。这种简单的请求-响应的IO模型,很明显是无法满足实际生产环境对高并发、高吞吐的要求,因此,系统通常会提供多种I/O模型,以提高I/O操作的效率。阻塞式I/O;非阻塞式IO;I/O多路复用模型信号驱动式IO;异步IO。同步I/O操作会导致请求进程阻塞,直到I/O操作完成;异步I/O操作不会导致请求进程阻塞。

Aspiresky的专栏 324

Linux I/O复用中select poll epoll模型的介绍及其优缺点的比較

关于I/O多路复用: I/O多路复用(又被称为“事件驱动”),首先要理解的是。操作系统为你提供了一个功能。当你的某个socket可读或者可写的时候。它能够给你一个通知。这样当配合非堵塞的socket使用时,仅仅有当系统通知我哪个描写叙述符可读了,我才去运行read操作。能够保证每次read...

weixin_34407348的博客 118

admin select 2 异步_linux中如何使用异步 I/O 提高应用程序的性能

I/O 模型在深入介绍 AIO API 之前,让我们先来探索一下 Linux 上可以使用的不同 I/O 模型。这并不是一个详尽的介绍,但是我们将试图介绍最常用的一些模型来解释它们与异步 I/O 之间的区别。图 1 给出了同步和异步模型,以及阻塞和非阻塞的模型。图 1. 基本 Linux I/O 模型的简单矩阵每个 I/O 模型都有自己的使用模式,它们对于特定的应用程序都有自己的优点。本节将简要对其...

weixin_28716723的博客 67

第63章 其他备选的 I/O模型

本章我们探究了针对标准I/O 模型之外的其他几种可选的I/O 模型。它们是:I/O 多路复用(select()和poll())、信号驱动I/O 以及Linux 专有的epoll API。所有这些机制都允许我们监视多个文件描述符,以查看哪个文件描述符上可执行I/O 操作。需要注意的是,所有这些机制并不实际执行I/O 操作。相反,一旦发现某个文件描述符处于就绪态,我们仍然采用传统的I/O 系统调用来完成实际的I/O 操作。

u010783439的博客 292

Linux系统的I/O操作与Java的I/O模型

1. **阻塞 I/O**:Java 的传统 I/O 模型(BIO)直接依赖 Linux 的阻塞 I/O 系统调用(如 `read()` 和 `write()`),每次 I/O 操作都会阻塞线程,直到操作完成。 2. **非阻塞 I/O 和 NIO**:Java NIO 的非阻塞 I/O 操作依赖于 Linux 提供的非阻塞 I/O 系统调用(如 `fcntl` 或 `ioctl`)

itsniu的博客 897
上一篇: shell 字符串操作
下一篇: OpenCDN2.0安装
firefoxbug
博客等级 码龄16年 259粉丝 165原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值