Chinaunix首页 | 论坛 | 博客
  • 博客访问: 21798
  • 博文数量: 17
  • 博客积分: 410
  • 博客等级: 下士
  • 技术积分: 111
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-22 22:04
文章分类

全部博文(17)

文章存档

2011年(17)

我的朋友
最近访客

分类: LINUX

2011-07-24 20:02:39

同步IO与异步IO的区别

首先要明确一点:不同IO模型之间的差别本质上是CPU的参与方式

这里重点说一下各自的应用场景

如何选择同步还是异步呢?
主要有这么几个指标供参考
1. 并发数量
2. 接收字节数
3. 处理请求所需CPU时间
我们一个一个来考察

并发数
并发低的时候同步IO与异步IO差别不大
并发高时差别会比较明显,这要表现在
1. 开启线程数:如并发1000时,同步IO要开启1000个线程,1000个线程要占用很多内存,这是其一,其二1000个线程间切换的时间也是很可观的;异步IO则可避免这个问题


接收字节数
接收字节越少被阻塞的概率越低,同步IO与异步IO的差别就越小
接收字节越多被阻塞的概率就越大,异步IO的优势越明显,能够同时服务更多的客户端请求

处理请求所需CPU时间
与同步异步没什么关系


同步阻塞IO
服务端在调用read()时,如果网卡缓冲区中没有数据则程序停止向下执行,直到网卡缓冲区中有数据。伪代码如下
Java代码 复制代码 收藏代码
  1. Before Blocking   
  2. Read(buffer);//读不到数据则一直等待   
  3. After blocking  
Before Blocking Read(buffer);//读不到数据则一直等待 After blocking

同步的非阻塞IO是这样的
服务端调用read()后,网卡缓冲区中如果没有数据可读就返回
服务器采用循环的方式再去读取 伪代码如下
Java代码 复制代码 收藏代码
  1. Byte[] buffer = new Byte[1024];   
  2. While(read(buffer)==0){ //read()返回读到的字节数   
  3.     //todo   
  4. }   
  5. processBuffer(); //处理读取的数据  
Byte[] buffer = new Byte[1024]; While(read(buffer)==0){ //read()返回读到的字节数 //todo } processBuffer(); //处理读取的数据

可以看出CPU大部分被浪费了


异步非阻塞IO
服务端调用read()方法,若网卡缓冲区中无数据则返回,程序继续向下执行。当缓冲区中有数据时,系统会通知应用程序。
Java nio中的selector可设置为异步非阻塞IO

异步阻塞IO
谁来补充下
google_protectAndRun("render_ads.js::google_render_ad", google_handleError, google_render_ad);
1
0
分享到:
评论
3 楼 2010-07-13   引用
xly_971223 写道
mercyblitz 写道
楼主是不是搞错了,Java NIO是同步非阻塞,在Linux 2.6以上的内核中,JDK6采用的epoll,如果前提条件不满足,则是select/poll的模式,都属于同步非阻塞IO。

多谢提醒 java nio确实是同步非阻塞的
如下伪代码
Java代码 复制代码 收藏代码
  1. Byte[] buffer = new Byte[1024];   
  2. While(read(buffer)>0){ //read()返回读到的字节数   
  3.     //todo   
  4. }   
  5. processBuffer(); //处理读取的数据  
Byte[] buffer = new Byte[1024]; While(read(buffer)>0){ //read()返回读到的字节数 //todo } processBuffer(); //处理读取的数据



不客气,呵呵。
2 楼 2010-07-13   引用
mercyblitz 写道
楼主是不是搞错了,Java NIO是同步非阻塞,在Linux 2.6以上的内核中,JDK6采用的epoll,如果前提条件不满足,则是select/poll的模式,都属于同步非阻塞IO。

多谢提醒 java nio确实是同步非阻塞的
如下伪代码
Java代码 复制代码 收藏代码
  1. Byte[] buffer = new Byte[1024];   
  2. While(read(buffer)>0){ //read()返回读到的字节数   
  3.     //todo   
  4. }   
  5. processBuffer(); //处理读取的数据  
Byte[] buffer = new Byte[1024]; While(read(buffer)>0){ //read()返回读到的字节数 //todo } processBuffer(); //处理读取的数据

1 楼 2010-07-12   引用
楼主是不是搞错了,Java NIO是同步非阻塞,在Linux 2.6以上的内核中,JDK6采用的epoll,如果前提条件不满足,则是select/poll的模式,都属于同步非阻塞IO。
阅读(576) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~