您的位置:首页 > 娱乐 > 明星 > 嘉兴网站制作计划_天眼查企业查询官网网页版_google官网入口手机版_北京seo代理公司

嘉兴网站制作计划_天眼查企业查询官网网页版_google官网入口手机版_北京seo代理公司

2025/4/10 1:01:31 来源:https://blog.csdn.net/zgwnb666/article/details/146018568  浏览:    关键词:嘉兴网站制作计划_天眼查企业查询官网网页版_google官网入口手机版_北京seo代理公司
嘉兴网站制作计划_天眼查企业查询官网网页版_google官网入口手机版_北京seo代理公司

IO

什么是IO,以字面的意思来讲,I就是input,O就是output嘛,所以在c++中常见的IO流,cout就是将数据输出出去,cin就是将数据输入进来!

那么IO的本质是在干什么事情呢?
以cin来举例子,输入一个数据分几步呢?简单来说可以分两步,我们需要等待用户输入数据,再将数据拷贝到特定的内存上!

所以:IO=等+拷贝;

我们常见的IO模式就是阻塞与非阻塞的区别了!
 

5种IO模型

阻塞IO

阻塞IO是我们常见的一种IO模型,像我们的read,write就是很典型的I阻塞O模型!在阻塞 IO 模式下,当应用程序执行 IO 操作(如从网络读取数据或从文件读取内容)时,程序会一直等待,直到操作完成或出现错误。在等待过程中,线程会被阻塞,无法执行其他任务,这意味着线程在 IO 操作进行期间处于暂停状态,不能继续执行后续的代码逻辑。

阻塞IO优点非常明显,就是最容易实现,用起来非常流畅,缺点也非常明显,就是他会去阻塞进程,进程就不会往下进行了。

非阻塞IO

在非阻塞 IO 模式下,当应用程序发起一个 IO 操作时,无论该操作是否能够立即完成,程序都不会被阻塞,而是会立即返回一个结果。如果操作不能立即完成,通常会返回一个特定的错误码(如EWOULDBLOCKEAGAIN),表示当前没有数据可读或写操作暂时无法进行。应用程序可以继续执行其他任务,并在之后的某个时间点再次尝试进行 IO 操作。

优点就是不会阻塞进程,缺点就是通过轮询的方式,就非常占用CPU资源。

信号驱动IO

信号驱动 I/O 允许进程在进行 I/O 操作时,通过信号机制来接收 I/O 完成的通知。进程可以预先向内核注册一个信号处理函数,当指定的 I/O 操作准备好时,内核会向进程发送一个信号,进程在接收到信号后,调用预先注册的信号处理函数来处理 I/O 操作。这样,进程在等待 I/O 操作完成的过程中可以继续执行其他任务,而不必像阻塞 I/O 那样一直等待,也无需像非阻塞 I/O 那样频繁地进行轮询。

相交于上面两种方案,优点就是不需要轮询,而且不用阻塞,缺点就是我们需要额外学习一些信号的知识!

IO多路转接

在传统的阻塞 I/O 模型中,一个线程一次只能处理一个 I/O 操作,如果要处理多个 I/O 流,就需要为每个流创建一个独立的线程,这会带来较大的线程创建和管理开销。而 IO 多路转接机制通过一个线程同时监视多个文件描述符,当某个文件描述符上有 I/O 事件发生时,才进行相应的处理,从而避免了创建大量线程,提高了系统的性能和资源利用率。

这种方法优点就是一次性可以监视多个文件描述符,在资源浪费上也比较少,主要是可以控制每次阻塞时间,唯一的缺点就是写起来可能比较麻烦!

异步IO

异步 I/O 允许程序在发起 I/O 操作后,无需等待该操作完成,就可以继续执行后续的代码。当 I/O 操作完成后,系统会通过某种方式(如回调函数、信号或事件通知)告知程序,程序再对操作结果进行处理。与阻塞 I/O 不同,异步 I/O 不会让线程在 I/O 操作期间处于阻塞状态;和非阻塞 I/O 相比,非阻塞 I/O 需要程序主动轮询操作状态,而异步 I/O 是由系统主动通知操作完成。 

优点:可以对代码的模块进行解耦,缺点就是这样的代码一般都会联系到多线程或者多进程的代码!

非阻塞IO代码编写

在Linux系统里边有一些接口让我们用来将IO变为非阻塞

#include <unistd.h>
#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );

fcntl 函数有5种功能:
• 复制一个现有的描述符(cmd=F_DUPFD).
• 获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD).
• 获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).
• 获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN).
• 获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW

比如我们要将一个文件设置为非阻塞

voidSetNoBlock(intfd){intfl=fcntl(fd,F_GETFL);if(fl<0){perror("fcntl");return;}fcntl(fd,F_SETFL,fl|O_NONBLOCK);}

现在我们将键盘输入流设置为非阻塞
 

#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include<cerrno>
using namespace std;bool SetNonBlocking(int fd)
{int flags = fcntl(fd, F_GETFL, 0);if (flags == -1){return false;}flags |= O_NONBLOCK;if (fcntl(fd, F_SETFL, flags) == -1){return false;}return true;
}void test1()
{SetNonBlocking(0); // 设置将输入文件设置为非阻塞while (1){//SetNonBlocking(0);char str[1024] = "please input a string:\n";write(1, str, sizeof(str)); //像屏幕设备打印消息char get[1024];int n=read(0, get, sizeof(get));    //从键盘设备读取数据if (n==0){cout<<"文件结束"<<endl;    //文件结束}else if(n>0){get[n]='\0';cout<<"input string is:"<<get<<endl; //打印输入的字符串}else{if(errno==EAGAIN||errno==EWOULDBLOCK)//errno==EAGAIN表示输入流没有数据,errno==EWOULDBLOCK表示输入流没有数据{cout<<"输入流没有数据"<<endl;}else if(errno==EINTR)//errno==EINTR表示信号中断,读取失败{cout<<"信号中断"<<endl;}else {perror("read error");//打印出错误信息}}sleep(1);    //睡眠1秒}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com