高级IO--1 ---(五种典型IO,阻塞IO,非阻塞IO,信号驱动IO,异步IO, IO多路转接)

高级IO:

五种典型IO:

阻塞IO/非阻塞IO/信号驱动IO/异步IO/IO多路转接
IO多路转接模型:select/poll/epoll

五种典型IO

阻塞IO

IO操作的流程:等待IO操作条件具备,然后进行数据拷贝
为了完成IO操作发起调用,若当前不具备IO操作条件,则等待,直到条件具备,完成IO操作后调用返回
在这里插入图片描述
钓鱼的时候,手里一直握着鱼竿,等待?上钩。

非阻塞IO

为了完成IO操作发起调用,若当前不具备IO操作条件,则立即报错返回;可以干点其他的事情,循环过来进行判断
在这里插入图片描述
把鱼竿放下去,去做其他事情,隔一段时间过来看一次,缺点:回来时?跑了。所以出现信号驱动IO
非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询. 这对CPU来说是较大的浪费, 一 般只有特定场景下才使用.

信号驱动IO

提前对IO信号自定义处理方式,当IO条件具备时,操作系统通过信号通知进程,这时候IO条件已经具备,直接发起调用进行数据拷贝
在这里插入图片描述
钓鱼的时候,抛出鱼竿,在鱼竿上绑上一个铃铛,如果?咬钩了,就能及时知道了

异步IO

IO操作条件的等待与数据拷贝都由操作系统来进行等待与操作,等到IO操作完成后,通过信号通知进程,进程直接对数据进行操作
在这里插入图片描述
钓鱼的时候,抛出鱼竿,找个人帮你钓鱼,调到?了,叫一下你

总结

IO几种操作中,IO操作效率越来越高,但是流程控制越来越复杂

高级IO重要概念

阻塞与非阻塞

  • 阻塞:当前不具备操作条件时,调用挂起等待,直到条件具备,完成操作后调用返回
  • 非阻塞:当前不具备操作条件,调用直接报错返回
  • 阻塞与非阻塞:关注的并不是操作是否完成,而是调用是否立即返回

同步通信 vs 异步通信

同步:当前不具备操作条件时,调用挂起等待,直到条件具备,完成操作后调用返回
异步:发起操作的调用,这个操作并不由自己完成,由别人完成
同步与异步:关注的是操作是否由自己完成
同步通常是阻塞的;但是异步有阻塞也有非阻塞

  • 异步阻塞:发起调用完成功能,功能由操作系统完成,但是进程自身一直等待操作系统完成完成,完成之后返回

  • 异步非阻塞:发起调用完成功能,功能由操作系统完成,进程自身立即返回

  • 所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回. 但是一旦调用返回,就得 到返回值了; 换句话说,就是由调用者主动等待这个调用的结果;

  • 异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果; 换句话说,当一个异步 过程调用发出后,调用者不会立刻得到结果; 而是在调用发出后,被调用者通过状态、通知来通知调用 者,或通过回调函数处理这个调用.

同步和异步关注的是消息通信机制.

了解Linux下的AIO—异步IO

https://blog.csdn.net/brucexu1978/article/details/7085924

IO多路转接/IO多路复用

对大量描述符进行事件监控(可读事件/可写事件/异常事件)监控
在这里插入图片描述

作用
  • 前边基本的tcp服务器只能与一个客户端通信一次
  • 因为服务器端不知道新的客户端连接请求以及客户端数据什么时候到来,因此程序流程只能写死,导致程序会卡死在accept/recv这里
  • 假设服务端若是知道什么时候新的客户端连接起来,这时候再调用accept;程序流程就不会卡再accept这里,假若服务端知道什么时候客户端的数据到来,然后再进行recv,程序流程就不会卡在recv这里
  • 这时候服务端就可以实现并发操作,谁有数据到来就操作谁,否则不进行操作
IO多路转接

替进程监控大量描述符什么时候有什么事件,进而进程可以针对发生了相应事件的描述符进行相应操作;

IO多路转接模型
  • select
  • poll
  • epoll

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

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

相关文章

IO多路转接模型----(select的模型,select的优缺点,poll的模型,poll的优缺点)

IO多路转接模型:select/poll/epoll 对大量描述符进行事件监控(可读/可写/异常) select模型 用户定义描述符的事件监控集合 fd_set(这是一个位图,用于存储要监控的描述符); 用户将需要监控的描述符添加到集合中,这个描…

IO多路转接模型-----epoll

epoll: Linux下性能最高的多路转接模型 epoll 有3个相关的系统调用. epoll_create 功能:创建epoll,在内核中创建eventpoll结构体,size决定了epoll最多监控多少个描述符,在Linux2.6.8之后被忽略,但是必须…

再写单链表(不带头单链表)

单链表 实际中链表的结构非常多样,以下情况组合起来就有8种链表结构: 单向、双向带头、不带头循环、非循环 虽然有这么多的链表的结构,但是我们实际中最常用还是两种结构: 无头单向非循环链表:结构简单&#xff0…

再写双向循环链表

#pragma once #include<assert.h> #include<malloc.h> #include<stdio.h> typedef int DLDataType;//定义链表结点结构 typedef struct DListNode{DLDataType value;struct DListNode *prev; //指向前一个结点struct DListNode *next; //指向后一个结点 } DL…

链表题目--1 删除链表中所有等于val的值

注意事项 要删除的结点相邻第一个结点就是要删除的结点 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val){if(headNULL){return NULL;}struct …

链表题目--2 求链表的中间结点 和 求链表中倒数第k个结点

求链表的中间结点 思路 一个走两步&#xff0c;一个走一步。一个走到尾&#xff0c;另外一个就走到了中间 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* middleNode(struct ListNode* head…

链表题目---3 合并两个有序单链表 和 分割链表

合并两个有序单链表 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){if(l1 NULL){return l2;}else if(l2 NULL){return l1;}struc…

链表题目---4 删除链表中重复的结点 和 判断链表是否为回文链表

删除链表中重复的结点 /* struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {} }; */ class Solution { public:ListNode* deleteDuplication(ListNode* pHead){if(pHead NULL){return NULL;}ListNode *prev NULL; //用于删除的结点, 是…

链表题目----5 相交链表 和 环形链表 和 返回链表开始入环的第一个节点

相交链表 思路 链表交叉不可能是x型因为有可能两个链表不等长&#xff0c;所以我们必须让他们从同一起跑位置去起跑从同一起跑位置出发&#xff0c;依次比较每个结点的地址是否相同 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct L…

链表题目---6 复制带随机指针的链表

思路 将新结点放在老结点的后面 复制random 将链表拆开 /* // Definition for a Node. class Node { public:int val;Node* next;Node* random;Node() {}Node(int _val, Node* _next, Node* _random) {val _val;next _next;random _random;} }; */ class Solution { publi…

括号匹配问题(c和c++版本实现)

括号匹配问题 思路 遇见左括号入栈&#xff0c;遇见一个右括号弹出栈顶元素右括号入栈前如果栈已经为空&#xff0c;则不匹配如果不为空则读取并弹出&#xff0c;弹出来的元素与右括号做比较&#xff0c;必须匹配&#xff0c;不匹配返回false;如果最后栈里还有元素&#xff0c…

用队列实现栈 AND 用栈实现队列

用队列实现栈 思路 入队列就是入栈出队列的时候&#xff0c;就是把前面size-1个队列中的元素先出&#xff0c;这样最后一个元素就成队首元素了&#xff0c;再把出去的元素再次入队列读栈顶元素&#xff0c;过程和第二步是一样的&#xff0c;就是弹出后&#xff0c;再把它入队列…

最小栈的实现(设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。)

最小栈的实现 思路 两个栈&#xff0c;左边栈接受元素&#xff0c;右边栈存最小的元素入栈时&#xff0c;先入左边栈&#xff0c;随后进行比较&#xff0c;左边和右边栈顶元素进行比较&#xff0c;如果新元素小&#xff0c;就把新元素放在右边的栈顶位置&#xff0c;如果新元素…

再写循环队列----c++实现

再写循环队列 class MyCircularQueue { public:/** Initialize your data structure here. Set the size of the queue to be k. */MyCircularQueue(int k) {array (int *)malloc(sizeof(int)*k);capacity k;size 0;front 0;rear 0;}/** Insert an element into the circu…

再谈二叉树(二叉树概念,二叉树的性质,二叉树的存储结构)

树的概念 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因 为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。它具有以下的特点&#xff1a;每个…

二叉树题目----1 前序中序后序遍历二叉树并返回相应的遍历(不是打印)

前序遍历 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*//*** Note: The returned array must be malloced, assume caller calls free().*/ int *array; int size;void _preorde…

二叉树题目----2 检查两颗树是否相同 和 对称二叉树的判定

检查两颗树是否相同 思路 根要相等 p->val q->val左子树相等 isSameTree(p->left,q->left)右子树也要相等 isSameTree(p->right,q->right) /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* …

二叉树题目---3 另一个树的子树 AND 二叉树最大深度

另一个树的子树 思路 两个数都遍历一遍&#xff0c;找到一个根结点相同时&#xff0c;判断以这个根结点为首的二叉树是否相等 前序遍历判断两棵树是否相同对于返回值的处理是难点 bool isSameTree(struct TreeNode *p, struct TreeNode *q) {if(p NULL && q NULL)…

二叉树题目----4 前序遍历重构二叉树 AND 求二叉树中所有结点的个数

前序遍历重构二叉树 思路 整个二叉树用数组存储因为先序遍历它先遍历根&#xff0c;再遍历左&#xff0c;左边没有跑完是不会去遍历右边的&#xff0c;所以遍历左子树&#xff0c;就是数组元素每回向后一个&#xff0c;个数-1遍历右边时&#xff0c;就是数组起始位置左子树跑到…

二叉树的进阶操作---(求二叉树中所有结点个数,求叶子结点个数,求第k层结点个数;在二叉树中查找某一结点;层序遍历;判断是否为完全二叉树)

typedef struct TreeNode {struct TreeNode *left;struct TreeNode *right;char val; }TreeNode;typedef struct Result{TreeNode * root; //构建的树的根结点int used; //构建过程中用掉的val个数 } Result;求二叉树中所有结点个数 void TreeSize(TreeNode *root, int …