什么是阻塞式IO,什么是非阻塞式IO?区分他们有何用?

阻塞式IO:IO即input/output,阻塞式IO指的是“一旦输入/输出工作没有完成,则程序阻塞,直到输入/输出工作完成”。在目前,我们从书本上学到的语法用的基本都是阻塞式IO。比如c语言的stdio.h库的所有函数(包含scanf(),getchar(),gets()等函数),Java的BIO(比如各类输入输出流)。他们都是不见黄河心不死的好汉。在你满足他们的条件之前,不让你的程序继续往下跑。最简单的例子:c语言的scanf()函数——当你scanf()要求输入两个数字时,你只输入一个数字,它也不会让你继续执行接下来的代码的。

非阻塞式IO:非阻塞式IO其实也并非完全非阻塞,通常都是通过设置超时来读取数据的。未超时之前,程序阻塞在读写函数上;超时后,结束本次读取,将已读到的数据返回。通过不断循环读取,就能够读到完整数据了。如果多次连续超时读到空数据的话,则可以断开。C语言的Socket可以使用setsockopt()来设置recv()超时(通常也就Socket需要考虑超时)。而JAVA有两种非阻塞式IO——AIO和NIO。说真的,我自己都没去看他们具体是怎么用的……所以我就不阐述了。

有啥用:就说说非阻塞IO的严重缺点吧。如果你企图保持socket的长连接,Server在规定的时间内没有读到Client的心跳,然而你Server读取socket传来的数据,调用的输入函数是阻塞式IO(如下),那么即便Client没有心跳了(Client已经断开了连接),你的Server程序仍然会被阻塞在该输入函数下无法继续等待数据结束标志(比如换行符)。然而,由于Client已经断开了连接,所以Sever永远收不到数据……这个线程就卡在这里结束不了,单纯地浪费资源了。(这时候,心跳包机制也成了鸡肋)

以下是JAVA阻塞式IO例子代码:

/*常见的阻塞式IO代码*/
serverSocket = new ServerSocket(PORT);
Socket client = serverSocket.accept();  BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));  while(1)
{  String reciver=in.readLine();//当输入流没有换行时,在此阻塞  Thread.sleep(1);
}  

那么,JAVA能否用阻塞式IO实现非阻塞式IO呢?

我这么问肯定是可以的。

之前用Java写的Server端代码,用的是一个连接对应一个线程的方式,发现Client结束长连接却不能终止Server的连接线程,但是又懒得去看NIO和AIO的资料,因为可能会动到之前写的代码(基本上把整个代码结构都推倒了),所以就偷了个懒,使用BIO来实现非阻塞式IO。

使用java的阻塞式IO实现非阻塞式IO

实现:相信学过操作系统原理的人都听说过生产者消费者问题吧。我也称这种实现方式为生产者消费者方式,然而目的和内容大相径庭。操作系统中的生产者消费者问题主要解决的问题是资源共享问题。而我解决的是供需问题。实现步骤如下——①写一个生产者类作为消费者的子线程:使用队列存放每一次读到的数据,不论是心跳还是目标数据都塞入队列。当队列不为空的时候,表示该socket口仍在接受数据,否则已经断开。②父线程(也就是消费者)不断向生产者索取数据,如果生产者在n*T的时间间隔内不断地返回“队列为空”的状态,则断开该socket,终止该消费者线程。

原理:通过父线程终止,强迫子线程(生产者类)抛出异常,从而终止输入输出流的持续阻塞状态。

以下是生产者类的代码:

/*生产者类*/
class dataProducer implements Runnable
{  BufferedReader in=null;  Queue<String> inputQueue=new LinkedList<String>();  public dataProducer(InputStream _inputer)  {  in=new BufferedReader(new InputStreamReader(_inputer));  }  public boolean isActive() //用于父线程判断生产者是否有数据可读  {  if(inputQueue.isEmpty())return false;  else return true;  }  public String next() //获得队列的下一个数据  {  return inputQueue.remove();  }  public void run()   {  try  {  while(true)  {  String reciver=in.readLine();  inputQueue.add(reciver);  Thread.sleep(10);  }  }  catch(IOException | InterruptedException e) //被强迫抛出异常后,该线程会执行以下代码  {  System.out.println("Forced interrupted the readline() successfully.");  e.printStackTrace();  }  finally   {  try   {  if(in!=null)in.close();  }   catch (IOException e)   {  e.printStackTrace();  }  }  }
}  

以下是父线程调用生产者类的代码:

long lasstime=System.currentTimeMillis();
long interval=0;
try
{    dataProducer rdl=new dataProducer(client.getInputStream());  Thread thrdl=new Thread(rdl);  thrdl.start();  while(interval<16000)  {  interval=System.currentTimeMillis()-lasttime;  if(!rdl.isActive()){Thread.sleep(10);continue;}  String reciver=rdl.next();  if(reciver 是数据) //判断姿势取决于你的心跳包和数据包怎么设计  {  //处理数据;  }  lasttime=System.currentTimeMillis(); //更新lasttime  Thread.sleep(1);  }
}
catch(Exception e)
{  //异常处理
}
finally
{  //资源回收
}  

怎么使用c语言实现非阻塞式socket线程?

实现:C语言使用socket实现长连接的话,可以通过setsockopt()来设置recv()的超时,自动跳出阻塞重新进入循环。能够设置超时的话,将超时时间设成n*T,再加个判断就行了。需要注意的是,设置recv()超时的同时,accpet()阻塞也会超时。没力气贴代码了,感觉能够设置超时还是挺方便的。

阻塞式IO和非阻塞式IO相关推荐

  1. 5种网络IO模型:阻塞IO、非阻塞IO、异步IO、多路复用IO、信号驱动IO

    目录 前言 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) 模型间的区别 ...

  2. 计算机网络——阻塞IO、非阻塞IO、IO多路复用

    1 简介   网络IO模型有5种:阻塞IO.非阻塞IO.IO多路复用.信号驱动IO.异步IO   本文仅对阻塞IO.非阻塞IO.IO多路复用进行讲解   在网络通信中,对数据进行收发在发送端和接收端的 ...

  3. 简单理解阻塞Io和非阻塞io

    https://www.kancloud.cn/lengyueguang/linux/1201612 有很多人把阻塞认为是同步,把非阻塞认为是异步:个人认为这样是不准确的,当然从思想上可以这样类比,但 ...

  4. 阻塞IO、非阻塞IO的区别

    阻塞IO.非阻塞IO的区别 1.类与类之间的关系:依赖,实现,泛化(继承),关联,组合,聚合. 1)依赖(虚线):一个类是 另一个类的函数参数 或者 函数返回值. 2)实现(实线加小圆):对纯虚函数类 ...

  5. 【网络编程】同步IO、异步IO、阻塞IO、非阻塞IO

    IO分两阶段: 1.数据准备阶段:在该阶段,根据是否等待数据准备,将IO分成阻塞和非阻塞: 2.内核空间复制回用户进程缓冲区阶段:在该阶段,只要程序需要等待复制完成,才能往下运行(尽管这个时间很短), ...

  6. 阻塞io阻塞io_Redis:RESP协议,阻塞IO 与非阻塞IO,Redis的线程模型

    1.Redis 阻塞IO 与非阻塞IO Java在JDK1.4 中引入了NIO ,但是也有很多人在使用阻塞IO,这两种IO有什么区别? 在阻塞模式下,如果你从数据流读取不到指定大小的数据量,IO就会阻 ...

  7. python复制文件夹不阻塞_Python学习第54天(阻塞(blocking) IO和非阻塞(non-blocking)IO)...

    今天之所以这么早结束,主要是因为自己脑子不够用了,发现最近的定义有点多,完全搞不清楚了,打算早点睡觉,今天的内容估计要引用很多别人的部分了. 看到题目的四个东东是不是惊呆了,我也是惊呆了,同时脑子还跟 ...

  8. 网络传输中的两个阶段、阻塞IO、非阻塞IO和多路复用

    今天学习了网络传输中的两个阶段.阻塞IO.非阻塞IO和多路复用 一.网络传输中的两个阶段 分别是 waitdata 和 copydata send就是copydata recv是waitdata和co ...

  9. 【多线程】0.理解一下5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO

    5种IO模型.阻塞IO和非阻塞IO.同步IO和异步IO 看了一些文章,发现有很多不同的理解,可能是因为大家入切的角度.环境不一样.所以,我们先说明基本的IO操作及环境. 本文是在<UNIX网络编 ...

最新文章

  1. hdu 2222:Keywords Search
  2. 我的程序员之路:上帝的苹果
  3. 对于白神贪心问题的感悟
  4. PostgreSQL在何处处理 sql查询
  5. matlab表达式,表达式 - MATLAB Simulink - MathWorks 中国
  6. 励志!从中专生到清华博士的逆袭人生
  7. ES6新语法--箭头函数
  8. ControllerContext分析
  9. Asp.net使用JQuery实现评论的无刷新分页及分段延迟加载效果
  10. java从入门到进阶
  11. 乐高机器人巡线C语言程序,乐高机器人巡线原理.doc
  12. 暴雪正在等待另一项_守望先锋更新一直显示正在等待另一项安装或更新怎么办...
  13. Flex使用ribbit.com的服务给手机发送短信SMS
  14. SpringBoot - 单元测试利器Mockito入门
  15. 秀动抢票教程,JS逆向分析与学习
  16. 智能窗帘控制(语音、时间、光、红外)
  17. 区块链面临的挑战(一)
  18. 导出开发板上的根文件系统,并打包制成img镜像
  19. 终身 服务器_阿里云VS腾讯云618年中活动云服务器价格对比哪个更优惠?
  20. 汇编实现通过输入被加数与加数,实现加法

热门文章

  1. 搜遍全网,终于找到一个适合新手入门的物联网教程
  2. 从头到尾彻底理解傅里叶变换算法
  3. 利用HTML5+CSS3+JS实现简单的钟表
  4. 【C++】STL简介(了解)
  5. 凸规划问题与二阶锥规划
  6. 如何解决跨站脚本攻击
  7. simulink模糊逻辑控制器的使用小结
  8. 裁剪TIF图像,代码简单,易懂(Arcpy)
  9. 关于博客的论文php,基于php的个人博客系统毕业设计论文
  10. Serverless 架构的 N 种可能,你 Pick 谁?