首页 > 系统相关 >day07(网络编程基础)Linux IO模型(阻塞IO、非阻塞IO、信号驱动IO(异步IO))

day07(网络编程基础)Linux IO模型(阻塞IO、非阻塞IO、信号驱动IO(异步IO))

时间:2024-09-10 22:24:39浏览次数:15  
标签:异步 设置 day07 阻塞 发送 描述符 IO

目录

场景假设

一.阻塞式IO:最常见、效率低、不耗费cpu

TCP粘包、拆包发生原因:

二.非阻塞IO:轮询、耗费CPU,可以处理多路IO

设置非阻塞的方式

1.通过函数自带参数设置

2.通过设置文件描述符的属性。把文件描述符的属性设置为非阻塞

三.信号驱动IO/异步IO:异步通知方式,需要底层驱动的支持(了解)


IO模型(4种):阻塞IO、非阻塞IO、信号驱动IO(异步IO)、IO多路复用

场景假设

假设妈妈有一个孩子,孩子在房间里睡觉,妈妈需要及时获知孩子是否醒了,如何做?

一.一直看着他,一直在一个房间呆着:不累,但是不能处理其他的事情  (阻塞IO)

二.时不时的进房间看看:累,但是可以处理其他事情                (非阻塞IO)

三.睡觉,听孩子哭不哭:互不耽误                (信号驱动IO)

一.阻塞式IO:最常见、效率低、不耗费cpu

阻塞I/O 模式是最普遍使用的I/O 模式,大部分程序使用的都是阻塞模式的I/O 。

缺省情况下(及系统默认状态),套接字建立后所处于的模式就是阻塞I/O 模式。

学习的读写函数在调用过程中会发生阻塞相关函数如下:

•读操作中的read、recv、recvfrom

读阻塞--》需要读缓冲区中有数据可读,读阻塞解除

•写操作中的write、send

写阻塞--》阻塞情况比较少,主要发生在写入的缓冲区的大小小于要写入的数据量的情况下,写操作不进行任何拷贝工作,将发生阻塞,一旦缓冲区有足够的空间,内核将唤醒进程,将数据从用户缓冲区拷贝到相应的发送数据缓冲区。

注意:sendto没有写阻塞

1)无sendto函数的原因:

sendto不是阻塞函数,本身udp通信不是面向链接的,udp无发送缓冲区,即sendto没有发送缓冲区,send是有发送缓存区的,即sendto不是阻塞函数。

2)UDP不用等待确认,没有实际的发送缓冲区,所以UDP协议中不存在缓冲区满的情况,在UDP套接字上进行写操作永远不会阻塞。

•其他操作:accept、connect

udp丢包

tcp粘包

tcp拆包

TCP粘包、拆包发生原因:

发生TCP粘包或拆包有很多原因,常见的几点:

1、要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包

2、待发送数据大于MSS(传输层的最大报文长度),将进行拆包(到网络层拆包 - id ipflags )。

3、要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包

4、接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包

粘包解决办法:

解决问题的关键在于如何给每个数据包添加边界信息,常用的方法有如下:

1、发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了。

2、发送端将每个数据包封装为固定长度,这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。

3、可以在数据包之间设置边界,如添加特殊符号,这样,接收端通过这个边界就可以将不同的数据包拆分开。

4、延时发送

https://www.cnblogs.com/111testing/p/12810253.htmlicon-default.png?t=O83Ahttps://www.cnblogs.com/111testing/p/12810253.html

二.非阻塞IO:轮询、耗费CPU,可以处理多路IO

•当我们将一个套接字设置为非阻塞模式,我们相当于告诉了系统内核:“当我请求的I/O 操作不能够马上完成,你想让我的进程进行休眠等待的时候,不要这么做,请马上返回一个错误给我。”

•当一个应用程序使用了非阻塞模式的套接字,它需要使用一个循环来不停地测试是否一个文件描述符有数据可读(称做polling)。

•应用程序不停的polling 内核来检查是否I/O操作已经就绪。这将是一个极浪费CPU 资源的操作。

•这种模式使用中不普遍。

设置非阻塞的方式

1.通过函数自带参数设置

2.通过设置文件描述符的属性。把文件描述符的属性设置为非阻塞
int fcntl(int fd, int cmd, ... /* arg */ );
功能:设置文件描述符属性
参数:
   fd:文件描述符
   cmd:设置方式 - 功能选择
        F_GETFL  获取文件描述符的状态信息     第三个参数化忽略
        F_SETFL  设置文件描述符的状态信息     通过第三个参数设置
        O_NONBLOCK  非阻塞
        O_ASYNC     异步
        O_SYNC      同步
  arg:设置的值  in
返回值:
      特殊选择返回特殊值 - F_GETFL  返回的状态值(int)
        其他:成功0  失败-1,更新errno
        
使用:0为例
  0-原本:阻塞、读权限  修改或添加非阻塞
  int flags=fcntl(0,F_GETFL);//1.获取文件描述符原有的属性信息
  flags = flags | O_NONBLOCK;//2.修改添加权限
  fcntl(0,F_SETFL,flags);    //3.将修改好的权限设置回去

三.信号驱动IO/异步IO:异步通知方式,需要底层驱动的支持(了解)

异步通知:异步通知是一种非阻塞的通知机制,发送方发送通知后不需要等待接收方的响应或确认。通知发送后,发送方可以继续执行其他操作,而无需等待接收方处理通知。

1. 通过信号方式,当内核检测到设备数据后,会主动给应用发送信号SIGIO。

2. 应用程序收到信号后做异步处理即可。

应用程序需要把自己的进程号告诉内核,并打开异步通知机制。

//1.设置将文件描述符和进程号提交给内核驱动
//一旦fd有事件响应, 则内核驱动会给进程号发送一个SIGIO的信号
   fcntl(fd,F_SETOWN,getpid());

//2.设置异步通知
    int flags;
    flags = fcntl(fd, F_GETFL); //获取原属性
    flags |= O_ASYNC;       //给flags设置异步   O_ASUNC 通知
    fcntl(fd, F_SETFL, flags);  //修改的属性设置进去,此时fd属于异步
    
//3.signal捕捉SIGIO信号 --- SIGIO:内核通知会进程有新的IO信号可用
//一旦内核给进程发送sigio信号,则执行handler
    signal(SIGIO,handler);

阻塞IO(Blocking IO)

非阻塞IO(Non-blocking IO)

信号驱动IO(Signal-driven IO)

同步性

同步

非同步

异步

描述

调用IO操作的线程会被阻塞,直到操作完成

调用IO操作时,如果不能立即完成操作,会立即返回,线程可以继续执行其他操作

当IO操作可以进行时,内核会发送信号通知进程

特点

最常见、效率低、不耗费cpu,

轮询、耗费CPU,可以处理多路IO,效率高

异步通知方式,需要底层驱动的支持

适应场景

小规模IO操作,对性能要求不高

高并发网络服务器,减少线程阻塞时间

实时性要求高的应用,避免轮询开销

标签:异步,设置,day07,阻塞,发送,描述符,IO
From: https://blog.csdn.net/QR70892/article/details/142072323

相关文章

  • [ZZULIOJ] 1041: 数列求和2 (两种方法)
    1.题目描述输入一个整数n,输出数列1-1/3+1/5-……前n项的和。输入:输入只有一个整数n。输出:结果保留2为小数,单独占一行。样例输入Copy3样例输出Copy0.872.方法一#include<iomanip>#include<iostream>usingnamespacestd;doublek=1,i,sum=0;intn;intma......
  • C# Console application start wpf window via Application, Encapsulates a Windows
    usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows;usingSystem.Windows.Controls;usingSystem.Windows.Data;usingSystem.Windows.Media.Imaging;namespaceConsoleApp73......
  • MIT6.824 课程-PrimaryBackupReplication
    PrimaryBackupReplication背景为实现可容错的服务器,主从备份是一种常用的解决方案:在开启了主动备份的系统中,备份服务器的状态需要在几乎任何时候都与主服务器保持一致,这样当主服务器失效后备份服务器才能立刻接管。实现主备间的状态同步主要包括以下两种方式:StateTransfer(......
  • C# console application main method new and start wpf window application
    1.NewConsoleapplication;2.Addreference,PresentationCoreandWindowsBase3.usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows;usingSystem.Windows.Controls;using......
  • Memory-Efficient Adaptive Optimization
    目录概符号说明SM3区间的划分代码AnilR.,GuptaV.,KorenT.,SingerY.Memory-efficientadaptiveoptimization.NeurIPS,2019.概本文提出了一种memory-efficient的优化器:SM3.符号说明\(t=1,\ldots,T\),optimizationrounds;\(w_t\in\mathbb{R}^d\),par......
  • Android Studio -> Android Studio 获取release模式和debug模式的APK
    AndroidStudio上鼠标修改构建类型Release版本激活路径:Moretoolwindows->BuildVariants->ActiveBuildVariant->releaseAPK路径:Project\app\build\intermediates\apk\app-release.apkDebug版本激活路径:Moretoolwindows->BuildVariants->ActiveBuildVariant->......
  • select函数详解:IO复用
    select函数概述select函数是一种用于实现I/O复用的方法,它可以让程序在多个文件描述符(例如套接字)之间进行选择,以便在其中任何一个或多个可用时执行I/O操作。这种机制使得程序能够更高效地处理多个I/O操作。下面将对select的原理和工作机制进行详细介绍,并分析select函数的优势和......
  • visualstudio 工具箱如何批量加载devexpress控件?
     1.DevExpress简单介绍        DevExpress是一套功能强大的‌.NET用户界面控件开发套包,广泛应用于企业内容管理、成本管控、进程监督、生产调度等领域。以下是DevExpress在不同平台和控件中的使用方法:DevExpressWinForms控件的使用方法‌TreeList控件‌:设置Dock属......
  • ECOM 2001 Term Project Description
    ECOM 2001 TermProjectDescriptionDue 30Septemberat 9:00AMAWSTIntroductionThe aim of thisproject is toprepare, evaluate and analyse stockmarket data and torecommend an optimalportfo- lioconsistingof two stocks. Youhavebeen......
  • 【Azure Service Bus】创建 ServiceBus 的Terraform脚本报错GetAuthorizationRule: In
    问题描述在使用Terraform部署ServiceBus时候,遇见了如下报错:Error:ErrormakingReadrequestonAzureServiceBusTopicAuthorizationRule:servicebus.TopicsClient#GetAuthorizationRule:Invalidinput:autorest/validation:validationfailed:parameter=authorization......