阻塞与非阻塞,同步与异步

(一)小情景模拟阻塞与非阻塞,同步与异步

所需材料:本人、普通水壶、水开后会发出响声的水壶

情景一:我主动用普通水壶去烧水(主动请求事件:同步),并且一直站在旁边等待水开(等待数据准备好在进行下一步,阻塞),然后做饭;     同步阻塞

情景二:我主动用普通水壶去烧水(主动请求事件)不需要一直检测,每隔一段时间会过来看水是否开了(没有一直等待事件:非阻塞,但还是存在主动查看事件的行为),一直到查看到水开之后做饭;同步非阻塞

情景三:我主动请求用水开后会发出响声的水壶去烧水然后一直站在那里,不会在每隔一段时间看水有没有开,而是等水开了水壶发出声音通知我(并不是我主动的查看水是否开了,而是等待数据就绪通知),我在做饭。 异步阻塞

情景四:我主动请求用水开后会发出响声的水壶去烧水(主动请求事件然后我去干别的事情(没有自己主动等待查看数据就绪并且去处理其他事情),等待水开后水壶发生通知我,我在去做饭。异步非阻塞

总结:

(1)阻塞和非阻塞是指进程访问的数据如果尚未就绪,进程是否需要等待;如果等待,则进入阻塞;如果不等待则为非阻塞;

(2)同步和异步是指访问数据的机制;
         同步一般指主动请求并等待I/O操作完毕的方式;当数据就绪后在都写的时候就必须阻塞;
         异步是指主动请求数据后可以继续处理其他任务,随后等待I/O操作完毕,这样在进程都写时就不会阻塞;

(3)阻塞与非阻塞的区别

     阻塞和非阻塞关注的是进程在等待调用结果(消息、返回值)时的状态。

     阻塞是指调用结果返回之前,当前进程会被挂起。调用进程只有在得到结果才会返回。

    非阻塞调用指不能立刻得到结果,该调用不会阻塞当前进程

(4)同步与异步的区别:

   同步与异步关注的是进程之间的协作方式,

   同步是A进程必须得到B进程通知才能去执行某件事(A执行),

   异步是指A进程通知B进程去执行然后立刻得到返回,然后就可以去做自己的事,B完成之后会给A发一个通知(B执行)。

(二)网络I/O模型

 (1)同步I/O模型: 阻塞I/O  非阻塞I/O     多路复用I/O    信号驱动式I/O
          异步I/O模型:异步I/O

(2)同步阻塞I/O

   对于网络socket流来说,主要分为两部分:一是等待网络分组到达,将分组内容拷贝到内核的某个缓冲区;二是将内核缓冲区内容拷贝给用户进程空间。 

     同步阻塞I/O

  • 首先现在应用进程系统调用recv接收数据,发现内核缓冲区没有就绪数据到达,就等待数据就绪;
  • 数据就绪好将内核缓冲区数据拷贝给进程空间,通知进程读取数据,这期间应用进程一直在等待数据就绪;
  • 同步阻塞I/O模型如下图所示:

(2)同步非阻塞I/O

  • 首先现在应用进程系统调用recvfrom接收数据,发现内核缓冲区没有就绪数据到达,就返回不处理,但还是会隔段时间查看数据是否就绪
  • 直到内核数据就绪,将内核缓冲区数据拷贝给进程空间,通知进程读取数据,这期间应用进程一直在等待数据就绪;
  • 同步非阻塞I/O模型如下图所示:

在linux下,可以通过设置socket使其变为non-blocking,这样socket就为一个非阻塞socket;

 

  • (3)同步多路复用I/O

多路I/O复用受阻于多个socket,只要检测到任意一个有可读事件,则应用进程就会读取阻塞数据。多路/O复用模型如图所示:

 

 

  • 图中阻塞于 select 调用,等待数据报套接字变为可读。当select返回套接字可读这一条件的时候,则调用 recvfrom 把所读数据报复制到应用进程缓冲区;
  • 同步非阻塞方式需要用户进程不停的轮询,而此时的多路I/O复用是由内核来帮他监听可读事件并通知他;
  • 同步非阻塞方式每次只能监听一个socket,而可以等待多个socket,能实现同时对多个IO端口进行监听,当其中任何一个socket的数据准好了,就能返回进行可读,然后进程再进行recvform系统调用,将数据由内核拷贝到用户进程;
  • UNIX/Linux 下的 select、poll、epoll 都是用来实现多路I/O复用的;
  • 不需要等待一个socket数据全部到达再处理,而是一部分socket的数据到达了就通知用户进程;
  • Linux下的I/O复用包括select、poll、epoll,这三都是用来监听自己负责的socket状态,当内核发现可读事件时通过应用程序并进行处理。
  • 为了实现服务器的高并发,经常使用I/O复用
  • 并发:比如一个服务器可以连接多个客户端;
  • 并行:在同一时间几个线程各自处理各自的事情

(4)信号驱动I/O模型

信号驱动式IO就是指进程预先告知内核,当某个描述符上发送事件时,内核使用信号通知相关进程。信号驱动式IO并没有实现真正的异步,因为通知到进程之后,依然是由进程来完成IO操作。

 

 

  • 首先开启套接字的信号驱动式IO功能,并且通过 sigaction 系统调用安装一个信号处理函数,该函数调用将立即返回,当前进程没有被阻塞,继续工作;
  • 当数据报准备好的时候,内核则为该进程产生 SIGIO 的信号;
  • 随后既可以在信号处理函数中调用 recvfrom 读取数据报,并且通知主循环数据已经准备好等待处理,也可以通知主循环让它读取数据报;(其实就是一个待读取的通知和待处理的通知);

 (5)异步式I/O

 

信号驱动式IO和异步IO的区别:

信号驱动式IO是进程事先建立SIGIO的信号处理程序(用sigaction设置IO信号的处理方式),有如果有数据到来,内核会给进程发一个信号,通知进程,进程捕获到这个信号就会去执行处理函数部分,一般在这个函数中执行IO操作(信号发生在IO之前,IO由进程完成)。

异步IO是有进程请求异步读操作,会把套接字描述符,缓冲区指针、缓冲区大小和文件偏移一起发给内核,如果有数据到来,内核会把数据拷到相应的位置,然后给进程发一个信号,如果数据没有来,也必须等数据来了,内核把数据拷完之后,才给进程发一个信号,由内核通知我们IO操作何时完成(信号发生在IO之后,IO由内核完成)

异步式I/O的模型

 

 

 

 

 

 

 


  •  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值