首页 > 其他分享 >阻塞与非阻塞、同步与异步 I/O模型

阻塞与非阻塞、同步与异步 I/O模型

时间:2023-07-20 21:02:08浏览次数:42  
标签:异步 与非 模型 阻塞 信箱 IO 信件 函数

I/O模型

Linux 下的五种I/O模型

  • 阻塞I/O(blocking I/O)
  • 非阻塞I/O (nonblocking I/O)
  • I/O复用(select 和poll) (I/O multiplexing)
  • 信号驱动I/O (signal driven I/O (SIGIO))
  • 异步I/O (asynchronous I/O (the POSIX aio_functions))

前四种都是同步,只有最后一种才是异步IO。

 

Winsock的异步IO模型有下面六种

  • select选择模型
  • WSAAsyncSelect 异步选择模型
  • WSAEventSelect 事件选择模型
  • Overlapped I/O 事件通知模型
  • Overlapped I/O 完成例程模型
  • IOCP模型

 

Linux 的几种I/O模型介绍:

阻塞I/O模型:

简介:进程会一直阻塞,直到数据拷贝完成
应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好。 如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空间,IO函数返回成功指示。

阻塞与非阻塞、同步与异步 I/O模型_非阻塞

 

可能阻塞套接字的Windows Sockets API调用分为以下四种:

1.输入操作: recv()、recvfrom()、WSARecv()和WSARecvfrom()函数。以阻塞套接字为参数调用该函数接收数据。如果此时套接字缓冲区内没有数据可读,则调用线程在数据到来前一直睡眠。

2.输出操作: send()、sendto()、WSASend()和WSASendto()函数。以阻塞套接字为参数调用该函数发送数据。如果套接字缓冲区没有可用空间,线程会一直睡眠,直到有空间。

3.接受连接:accept()和WSAAcept()函数。以阻塞套接字为参数调用该函数,等待接受对方的连接请求。如果此时没有连接请求,线程就会进入睡眠状态。

4.外出连接:connect()和WSAConnect()函数。对于TCP连接,客户端以阻塞套接字为参数,调用该函数向服务器发起连接。该函数在收到服务器的应答前,不会返回。这意味着TCP连接总会等待至少到服务器的一次往返时间。

非阻塞I/O模型

简介:非阻塞IO通过进程反复调用IO函数(多次系统调用,并马上返回);在数据拷贝的过程中,进程是阻塞的;

我们把一个SOCKET接口设置为非阻塞就是告诉内核,当所请求的I/O操作无法完成时,不要将进程睡眠,而是返回一个错误。这样我们的I/O操作函数将不断的测试数据是否已经准备好,如果没有准备好,继续测试,直到数据准备好为止。在这个不断测试的过程中,会大量的占用CPU的时间。

 

阻塞与非阻塞、同步与异步 I/O模型_非阻塞_02

非阻塞套接字在控制建立的多个连接,在数据的收发量不均,时间不定时,明显具有优势。这种套接字在使用上存在一定难度,但只要排除了这些困难,它在功能上还是非常强大的。

 

I/O复用模型

简介:主要是select和epoll;对一个IO端口,两次调用,两次返回,比阻塞IO并没有什么优越性;关键是能实现同时对多个IO端口进行监听;

I/O复用模型会用到select、poll、epoll函数,这几个函数也会使进程阻塞,但是和阻塞I/O所不同的的,这两个函数可以同时阻塞多个I/O操作。而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时,才真正调用I/O操作函数。

 

阻塞与非阻塞、同步与异步 I/O模型_非阻塞_03

 

 

信号驱动I/O模型

 

简介:两次调用,两次返回;

首先我们允许套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。

 

阻塞与非阻塞、同步与异步 I/O模型_套接字_04

 

异步I/O模型

简介:数据拷贝的时候进程无需阻塞。
当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的输入输出操作

阻塞与非阻塞、同步与异步 I/O模型_套接字_05

 

5种I/O模型的比较:

 

阻塞与非阻塞、同步与异步 I/O模型_数据_06

 

 

Windows I/O模型介绍

网上有个比喻很好的说明这些模型,在这里引用一下。
老陈有一个在外地工作的女儿,不能经常回来,老陈和她通过信件联系。他们的信会被邮递员投递到他们的信箱里。

select模型


老陈非常想看到女儿的信。以至于他每隔10分钟就下楼检查信箱,看是否有女儿的信~~~~~
在这种情况下,“下楼检查信箱”然后回到楼上耽误了老陈太多的时间,以至于老陈无法做其他工作。

WSAAsyncSelect模型


后来,老陈使用了微软公司的新式信箱。这种信箱非常先进,一旦信箱里有新的信件,盖茨就会给老陈打电话:喂,大爷,你有新的信件了!从此,老陈再也不必频繁上下楼检查信箱了,牙也不疼了,你瞅准了,蓝天……不是,微软~~~~~~~~

WSAEventSelect模型


后来,微软的信箱非常畅销,购买微软信箱的人以百万计数……以至于盖茨每天24小时给客户打电话,累得腰酸背痛,喝蚁力神都不好使~~~~~~
微软改进了他们的信箱:在客户的家中添加一个附加装置,这个装置会监视客户的信箱,每当新的信件来临,此装置会发出“新信件到达”声,提醒老陈去收信。盖茨终于可以睡觉了。

Overlapped I/O 事件通知模型


后来,微软通过调查发现,老陈不喜欢上下楼收发信件,因为上下楼其实很浪费时间。于是微软再次改进他们的信箱。新式的信箱采用了更为先进的技术,只要用户告诉微软自己的家在几楼几号,新式信箱会把信件直接传送到用户的家中,然后告诉用户,你的信件已经放到你的家中了!老陈很高兴,因为他不必再亲自收发信件了!

Overlapped I/O 完成例程模型


老陈接收到新的信件后,一般的程序是:打开信封—-掏出信纸—-阅读信件—-回复信件……为了进一步减轻用户负担,微软又开发了一种新的技术:用户只要告诉微软对信件的操作步骤,微软信箱将按照这些步骤去处理信件,不再需要用户亲自拆信/阅读/回复了!老陈终于过上了小资生活!

IOCP模型


微软信箱似乎很完美,老陈也很满意。但是在一些大公司情况却完全不同!这些大公司有数以万计的信箱,每秒钟都有数以百计的信件需要处理,以至于微软信箱经常因超负荷运转而崩溃!需要重新启动!微软不得不使出杀手锏……
微软给每个大公司派了一名名叫“Completion Port”的超级机器人,让这个机器人去处理那些信件!

其实,上面每种模型都有优点,要根据程序需求而适当选择合适的模型,前面三种模型效率已经比较高,实现起来难道不大,很多一般的网络程序都采用前三种模型,只有对网络要求特别高的一些服务器才会考虑用后面的那些模型。MFC中的CAsyncSocket类就是用的WSAAsyncSelect模型,电驴中也是用的这种,不过在寻找对应socket的时候进行了优化,查找更快,在GridCast中采用的是WSAEventSelect模型,等待。

 

Java的I/O模型

OIO

OIO 就是同步I/O,

NIO

在JDK 1.4版本之后才开始支持异步IO,其实NIO也是使用操作系统的IO模型,但在各操作系统上的实现方式也不太一样

在Windows系统使用的是Select模型,而不是性能更高的IOCP,原因就是并非所有Windows都支持IOCP,IOCP在windows NT 3.5中被引入,只支持WindowsNT和windows 2000。(参考:

在Linux系统上使用的是多路复用IO,JDK 6之前用的是poll模型,JDK 7中使用epoll。(参考:)

AIO

JDK 7中出现了AIO,其实AIO就是NIO的增强版,因为JDK 6之前用的是poll,JDK 7用的是epoll,而epoll就是poll的增强版。

 

 

参考资料:


Java NIO和操作系统I/O模型
http://wugc.iteye.com/blog/986997 

IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)

Java NIO原理 图文分析及代码实现
http://weixiaolu.iteye.com/blog/1479656

Java IO模型

Windows I/O模型、同步/异步、阻塞/非阻塞
http://www.linuxnote.org/windows-i-o-model-synchronous-asynchronous-blocking-non-blocking.html

标签:异步,与非,模型,阻塞,信箱,IO,信件,函数
From: https://blog.51cto.com/u_15588078/6791414

相关文章

  • 异步处理架构应用范围
    异步处理架构应用范围异步处理架构是一种在软件开发中广泛应用的设计模式,它可以提高系统的性能和可伸缩性,并改善用户体验。在本文中,我们将介绍异步处理架构的概念、应用范围以及一个简单的代码示例。什么是异步处理架构?在传统的同步处理架构中,一个请求到达系统后,系统会立即处理......
  • 异步 Async & Await
    async在C#世界里是上下文关键字。它只有在修饰一个方法的时候才自动被编译器识别为关键字,在代码的其他位置上可以被用作变量名等其他任何用途。async关键字用来修饰两类方法: lambda表达式或者异步方法。拥有async修饰的方法称为async方法,比如:就如上面这个方法ExampleMethodAs......
  • IC卡读卡器web插件中使用js异步await/async调用接口
    js中使用异步await/async方式,对于程序的结构和逻辑都有非常大的好处,对于异步await/async有如下描述:async表示这是一个async函数,await只能用在async函数里面,不能单独使用.async返回的是一个Promise对象,await就是等待这个promise的返回结果后,再继续执行.await等待的是一个Pro......
  • Asp.Net Core 实现异步操作锁 (SemaphoreSlim)
    /设置同时访问线程最大数量staticSemaphoreSlim_semaphore=newSemaphoreSlim(4);staticvoidAccessDatabase(stringname,intseconds){Console.WriteLine($"{name}waitstoaccessadatabase");_semaphore.Wait();Console.WriteLine($"{name}wa......
  • 阻塞队列
    阻塞队列是一个支持两个附加操作的队列,这两个附加操作支持阻塞的插入和移除操作。1、支持阻塞的插入方法:当队列满时,队列对阻塞插入元素的线程,直到队列不满。2、支持阻塞的移除方法:当队列为空,获取元素的线程会等待队列变味非空。阻塞队列常用的应用场景常用于生产者和消费者场景,生产......
  • java异步调用延迟执行
    Java异步调用延迟执行简介在Java开发中,我们经常需要处理一些耗时的操作,而为了提高程序的性能和用户体验,我们通常会采用异步调用的方式来执行这些耗时操作。异步调用可以让主线程继续执行其他任务,而不需要等待耗时操作完成。本文将介绍如何在Java中实现异步调用延迟执行的方法,并......
  • UART——通用异步收发传输器
    特点:发送—并转串;接收—串转并;全双工传输1、发送:常见设置包含:起始位、数据位、波特率、奇偶校验类型、停止位、空闲位(1)起始位先发一个逻辑0,表示传输字符开始,依靠检测起始位来实现发送与接收方的时间同步。(2)数据位单个UART数据传输的数据位数,可以是5、6、7或8(默认)(3......
  • useEffect、异步请求、定时器使用useState闭包问题
    useEffect闭包问题:问题:useEffect使用useState会使调用的所有方法内部的state值为useEffect周期的值,即使在这个过程中useState的值变化也不能影响调用方法内获取到原始值解决方式:使用useCallabck可以避免由此产生的闭包问题异步请求、定时器等js闭包问题:问题:异步请求和定时器......
  • 【Python】从同步到异步多核:测试桩性能优化,加速应用的开发和验证
    测试工作中常用到的测试桩mock能力在我们的测试工作过程中,可能会遇到多个项目并行开发的时候,后端服务还没有开发完成,或者我们需要压测某个服务,这个服务测在试环境的依赖组件(如MQ)无法支撑我们svr的并发访问的场景,这个时候我们可能就需要手写一个服务,来替代测试环境的这些依赖组......
  • 【一】Ajax与异步编程之web服务端
    【一】Ajax与异步编程之web服务端Ajax属于客户端网络技术,属于js范畴。基于aiohttp模Ajax与异步编程之web服务端块构建一个提供http协议的web服务器,并准备数据给客户端请求使用。pipinstallaiohttppipinstallaiohttp_corsserver.pyfromaiohttpimportwebimporta......