Linux四种I/O模型

一.四种模型

阻塞式IO,非阻塞式IO,信号驱动IO,IO多路复用

二.阻塞式IO

特点:最简单,最常用,效率低

阻塞I/O 模式是最普遍使用的I/O 模式

  系统默认状态,套接字建立后所处于的模式就是阻塞I/O 模式。

  目前学习的读写函数中会发生阻塞相关函数如下:

 ·      read、recv、recvfrom

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

 ·      write, send 

         写阻塞--》阻塞就是写入数据时遇到缓冲区满了的情况,需要等待缓冲区有空间后才能继续写入, 所以写阻塞发生的情况比较少.

 ·      accept    connect

需要注意的是使用UDP时,UDP没有发送缓存区 ,则sendto没有阻塞

 1)UDP通信无连接,且无发送缓冲区(不怕粘包),即sendto在UDP中没有发送缓冲区。

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

UDP与TCP缓存区 

UDP是一种无连接的传输协议,它不保证数据的可靠性和顺序性, 所以不需要考虑连接和缓存,而是将数据尽快发送出去,不关心数据是否到达目标主机或者是否按照发送顺序到达. 但是UDP有接受缓存区, 因为数据发送过快, 如果接收缓存区内数据已满, 则继续发送数据, 可能会出现丢包。

TCP是一种面向连接的传输协议,有发送缓存区和接收缓存区, 如果发送频率过快, 且内容小于发送缓存区的大小 , 可能会导致多个数据的粘包。如果发送的数据大于发送缓存区的剩余大小,send将会阻塞,  在阻塞期间,send函数会自动拆分数据包发送,直到所有数据都被发送完毕或者发送缓冲区的空间不足以继续发送为止, 这就是拆包。

UDP不会造成粘包和拆包,  TCP不会造成丢包

UDP_数据报:  本质是独立的包, 有边界;

TCP_流,:本质是字节流形式, 一帧一帧发送,且每一帧没有边界,一帧丢失会重新补发;

  

 

 三.阻塞式IO

特点:可以处理多路IO,需要轮询,大量浪费CPU资源

  1. 当一个应用程序使用了非阻塞模式的套接字,则它需要使用一个循环来不停的测试是否一个文件描述符有数据可读。
  2. 应用程序不停的测试,会占用大量的cpu资源 ,所以说一般不适用

 将recv设置为非阻塞时, recv在接收缓存区内, 未拿到客户端发送来的数据, 那么recv就会报错 , 所以会一直打印 recv is err: 资源不可用

fcntl设置文件描述符的属性

声明: int fcntl (int fd, int cmd, ...arg);

头文件: #include<fcntl.h>      #include<unistd.h>

功能:设置文件描述符的属性

参数:fd:文件描述符

         cmd: 操作功能选项 (可以定义个变量,通过vi -t F_GETFL 来找寻功能赋值 )

          F_GETFL:获取文件描述符的原有的状态信息 

          //不需要第三个参数,返回值为获取到的属性

          F_SETFL:设置文件描述符的状态信息 - 需要填充第三个参数

          //需要填充第三个参数  O_RDONLY, O_RDWR ,O_WRONLY ,O_CREAT

                  O_NONBLOCK 非阻塞   O_APPEND追加

                  O_ASYNC 异步        O_SYNC  同步 

          F_SETOWN:    可以用于实现异步通知机制。

        //当文件描述符上发生特定事件时(例如输入数据到达),内核会向拥有该  文件描述符 的进程发送 SIGIO 信号(异步),以便进程能够及时处理这些事件。

        arg:文件描述符的属性      --------------------同上参数

返回值: 特殊选择:根据功能选择返回 (int 类型)

            其他:  成功0   失败: -1;

改变步骤:

1.获取该文件描述符0 (标准输入) 的原属性 : 标准输入原本具有阻塞的功能  

int flag = fcntl(0, F_GETFL); //获取文件描述符原有信息后,保存在flag变量内

2.修改对应的位nonblock(非阻塞)

int flag |= O_NONBLOCK; 

3. 将修改好的属性写回去 (0 标准输入 -- 阻塞  改为  非阻塞)

fcntl (0, F_SETFL, flag); //文件描述符   设置状态  添加的新属性

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>int main(int argc, char const *argv[])
{char buf[64] = {0};while (1){int flag = fcntl(0, F_GETFL); flag |= O_NONBLOCK;fcntl(0, F_SETFL, flag);fgets(buf, sizeof(buf), stdin);sleep(1);printf("buf: %s\n",buf);}return 0;
}

四.信号驱动IO

特点:异步通知模式,需要底层驱动支持

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

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

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

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

 步骤:

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);

#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>int fd;
void handler(int set)
{char buf[128] = {0};int len = read(fd, buf, sizeof(buf));buf[len] = '\0';printf("%s\n", buf);
}
int main(int argc, char const *argv[])
{fd = open("/dev/input/mouse0", O_RDONLY);if (fd < 0){perror("open err");return -1;}fcntl(fd, F_SETOWN, getpid());int flags = fcntl(fd, F_GETFL);flags |= O_ASYNC;fcntl(fd, F_SETFL, flags);signal(SIGIO, handler);char buf[128] = {0};while (1){fgets(buf, sizeof(buf), stdin);printf("%s", buf);}return 0;
}

 signal信号处理相关函数

头文件: #include <signal.h>

        typedef void (*sighandler_t)(int);

        sighandler_t   signal(int signum, sighandler_t handler)

功能:信号处理函数(注册信号)

参数: int signum:要处理的信号(要修改的信号)

           sighandler_t handler: 函数指针: void(*handler)(int) (修改的功能:)

           handler:------void handler(int num) 自定义的信号处理函数指针

返回值: 成功:设置之前的信号处理方式

失败:   SIG_ERR

 五.IO多路复用

帮助TCP实现并发服务器

特点:

  1. 进程中若需要同时处理多路输入输出 ,在使用单进程和单线程的情况下, 可使用IO多路复用处理多个请求;
  2. IO多路复用不需要创建新的进程和线程, 有效减少了系统的资源开销。

就比如服务员给50个顾客点餐,分两步:

       顾客思考要吃什么(等待客户端数据发送)

       顾客想好了,开始点餐(接收客户端数据)

要提高效率有几种方法? 

  1.  安排50个服务员   (类似于多进程/多线程实现服务器连接多个客户端,太占用资源)
  2. 哪个顾客想好了吃啥, 那个顾客来柜台点菜 (类似IO多路复用机制实现并发服务器)

 实现IO多路复用的方式:  select   poll   epoll

六.Linux四种IO模型对比

linux下的四种IO模型假设:

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

  阻塞式IO:    进到房间陪孩子一起睡觉,孩子醒了吵醒妈妈,不累,但是不能干别的了

  非阻塞式IO: 时不时进房间看一下:简单,空闲时间还能干点别的,但是很累

  信号驱动IO:  妈妈在客厅干活,小孩醒了他会自己走出房门告诉妈妈:互不耽误

假设妈妈有三个孩子, 分别在不同房间睡觉, 需要及时检测每个房间信息, 如何做?

   阻塞式IO:  阻塞处理多条路, 得不到该目的;

   非阻塞IO:  一直轮询, 大量占用CPU;

   多线程多进程, 或IO多路复用, 可以做到; 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国家网络安全周2023时间是什么时候?有什么特点?谁举办的?

国家网络安全周2023时间是什么时候&#xff1f; 2023年国家网络安全宣传周将于9月11日至17日在全国范围内统一开展。其中开幕式等重要活动将在福建省福州市举行。今年网安周期间&#xff0c;除开幕式外&#xff0c;还将举行网络安全博览会、网络安全技术高峰论坛、网络安全微视…

【Git】万字git与gitHub

&#x1f384;欢迎来到边境矢梦的csdn博文&#x1f384; &#x1f384;本文主要梳理在git和GitHub时的笔记与感言 &#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一下&#x1faf0;&…

【FAQ】安防监控/视频汇聚/云存储/智能视频分析平台EasyCVR显示CPU过载,如何解决?

视频云存储/安防监控/视频汇聚平台EasyCVR基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。安防视频监控系统EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、云…

线性代数的本质(四)——行列式

文章目录 行列式二阶行列式 n n n 阶行列式行列式的性质克拉默法则行列式的几何理解 行列式 二阶行列式 行列式引自对线性方程组的求解。考虑两个方程的二元线性方程组 { a 11 x 1 a 12 x 2 b 1 a 21 x 1 a 22 x 2 b 2 \begin{cases} a_{11}x_1a_{12}x_2b_1 \\ a_{21}x_…

无涯教程-JavaScript - COLUMNS函数

描述 COLUMNS函数返回数组或引用中的列数。 语法 COLUMNS (array)争论 Argument描述Required/OptionalarrayAn array or array formula, or a reference to a range of cells for which you want the number of Columns.Required Notes COLUMNS(1:1)返回Excel中的列数,即…

【python手写算法】numpy实现简易神经网络和反向传播算法【1】

import numpy as npdef dense(A,W):Znp.matmul(A,W)#矩阵乘法return 1/(1np.exp(-Z))if __name__ __main__:leanring_rate100Anp.array([[200.0,17.0]])# Wnp.array([[1,-3,5],# [-2,4,-6]])# bnp.array([[-1,1,2]])W1 np.array([[0., -10, 4],[-1,3,2]])W2np.ar…

STM32单片机——串口通信(轮询+中断)

STM32单片机——串口通信&#xff08;轮询中断&#xff09; 串口通信相关概念HAL库解析及CubeMX工程配置与程序设计常用函数介绍CubeMX工程配置HAL库程序设计&#xff08;轮询中断&#xff09;轮询数据收发中断收发数据 固件库程序设计及实现固件库配置流程结构体配置及初始化程…

React复习日志大纲

文章目录 React基础篇创建项目启动项目项目目录说明调整项目src剩余目录01基本使用02 列表渲染03 条件渲染04 样式处理05 函数和类组件创建和渲染06 事件绑定07 事件对象e08 传递额外参数09 组件状态修改10 受控组件11 非受控组件12 组件通信父传子13 Props说明14 组件通信子传…

Golang代码漏洞扫描工具介绍——govulncheck

Golang Golang作为一款近年来最火热的服务端语言之一&#xff0c;深受广大程序员的喜爱&#xff0c;笔者最近也在用&#xff0c;特别是高并发的场景下&#xff0c;golang易用性的优势十分明显&#xff0c;但笔者这次想要介绍的并不是golang本身&#xff0c;而且golang代码的漏洞…

Linux网络编程

一.协议 1.1什么是协议 从应用的角度出发&#xff0c;协议可理解为“规则”&#xff0c;是数据传输和数据的解释的规则。 假设&#xff0c;A、B双方欲传输文件。规定: 第一次&#xff0c;传输文件名&#xff0c;接收方接收到文件名&#xff0c;应答OK给传输方; 第二次&#xff…

【每日一题】34. 在排序数组中查找元素的第一个和最后一个位置

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 […

vscode-server

1know_host清除 2 删除服务器里的home/user/.vscode-server&#xff08;不是根root下的vscode-server&#xff09;&#xff0c;删除时用户名保持一致。 3 ssh配置文件 /etc/ssh/sshd_config[想改变,使用root&#xff0c;修改文件权限] 4 删除修改后&#xff0c;重启Windows下…

打造生产级Llama大模型服务

对于任何想要尝试人工智能或本地LLM&#xff0c;又不想因为意外的云账单或 API 费用而感到震惊的人&#xff0c;我可以告诉你我自己的旅程是如何的&#xff0c;以及如何开始使用廉价的消费级硬件执行Llama2 推理 。 这个项目一直在以非常活跃的速度发展&#xff0c;这使得它非…

父域 Cookie实现sso单点登录

单点登录&#xff08;Single Sign On, SSO&#xff09;是指在同一帐号平台下的多个应用系统中&#xff0c;用户只需登录一次&#xff0c;即可访问所有相互信任的应用系统。Cookie 的作用域由 domain 属性和 path 属性共同决定。在 Tomcat 中&#xff0c;domain 属性默认为当前域…

Python浪漫星空

系列文章 序号文章目录直达链接1浪漫520表白代码https://want595.blog.csdn.net/article/details/1306668812满屏表白代码https://want595.blog.csdn.net/article/details/1297945183跳动的爱心https://want595.blog.csdn.net/article/details/1295031234漂浮爱心https://wan…

校园网web免认真,大量服务器

服务器加满了&#xff0c;没有几个人来&#xff0c;传点图片看实力 什么方法解web认证方式校园网&#xff1f; 一般的校园网是对学生免费开放的&#xff0c;假如你是学生输入学号密码上网就是了&#xff0c;假如你不是那就是想蹭网了&#xff0c;再假如你不想让管理员或上网行为…

数据分享|R语言逻辑回归、线性判别分析LDA、GAM、MARS、KNN、QDA、决策树、随机森林、SVM分类葡萄酒交叉验证ROC...

全文链接:http://tecdat.cn/?p27384 在本文中&#xff0c;数据包含有关葡萄牙“Vinho Verde”葡萄酒的信息&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 介绍 该数据集&#xff08;查看文末了解数据获取方式&#xff09;有1599个观测值和12个变量&#xf…

pdf添加水印

给pdf文件添加水印 引入依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.3</version></dependency>添加水印 package com.it2.pdfdemo02.util;import com.itextpdf.tex…

用 Pytest+Allure 生成漂亮的 HTML 图形化测试报告

本篇文章将介绍如何使用开源的测试报告生成框架 Allure 生成规范、格式统一、美观的测试报告。 通过这篇文章的介绍&#xff0c;你将能够&#xff1a; 将 Allure 与 Pytest 测试框架相结合&#xff1b; 如何定制化测试报告内容 执行测试之后&#xff0c;生成 Allure 格式的测…

免费和开源的机器翻译软件LibreTranslate

什么是 LibreTranslate &#xff1f; LibreTranslate 免费开源机器翻译 API&#xff0c;完全自托管。与其他 API 不同&#xff0c;它不依赖于 Google 或 Azure 等专有提供商来执行翻译。它的翻译引擎由开源 Argos Translate 库提供支持。 这个软件在 2022 年 3 月的时候折腾过&…