NIO(四)—— 什么是同步IO?什么是异步IO?

       同步IO: 如果一个线程请求进行IO操作,在IO操作完成之前,该线程会被阻塞;

       异步IO: 如果一个线程请求进行IO操作,IO操作不会导致请求线程被阻塞。

 

       事实上,同步IO和异步IO模型是针对用户线程和内核的交互来说的:

       对于同步IO:当用户发出IO请求操作之后,如果数据没有就绪,需要通过用户线程或者内核不断地去轮询数据是否就绪,当数据就绪时,再将数据从内核拷贝到用户线程;

       而异步IO:只有IO请求操作的发出是由用户线程来进行的,IO操作的两个阶段都是由内核自动完成,然后发送通知告知用户线程IO操作已经完成。也就是说在异步IO中,不会对用户线程产生任何阻塞。

       这是同步IO和异步IO关键区别所在,同步IO和异步IO的关键区别反映在数据拷贝阶段是由用户线程完成还是内核完成。所以说异步IO必须要有操作系统的底层支持。

 

       阻塞IO和非阻塞IO是反映在当用户请求IO操作时,如果数据没有就绪,是用户线程一直等待数据就绪,还是会收到一个标志信息这一点上面的。也就是说,阻塞IO和非阻塞IO是反映在IO操作的第一个阶段,在查看数据是否就绪时是如何处理的。

 

 

 

 

### 异步IO实现原理 #### glibc中的AIO机制 在glibc中,异步IO的实现基于多线程同步来模拟异步行为。为了减少因频繁创建和销毁线程带来的开销,在面对多个请求的情况下,glibc AIO采用线程池技术[^1]。 ```c // 创建并初始化aio控制块结构体 struct aiocb my_aiocb; memset(&my_aiocb, 0, sizeof(struct aiocb)); ``` #### Java中的异步复用I/O 对于Java而言,其异步复用I/O(即非阻塞I/O或异步I/O)旨在提升系统并发处理能力与资源利用效率。这种模式允许线程无需等待I/O操作结束即可继续其他任务,主要借助NIO框架、`CompletableFuture`类以及响应式编程模型达成此目的[^2]。 ```java AsynchronousFileChannel channel = AsynchronousFileChannel.open(path); channel.read(buffer, position, attachment, new CompletionHandler<Integer, Object>() { @Override public void completed(Integer result, Object att) { /* ... */ } @Override public void failed(Throwable exc, Object att) {/* ... */} }); ``` #### Rust里的异步编程基础 至于Rust语言,则是建立在其操作系统所提供的底层异步设施之上的。尽管开发者能够仅依靠async/await语法糖来进行流程管理,不过通常还是会选择运用这些特性去实施真正的异步输入输出操作。值得注意的是,即便高级别的抽象简化了许多复杂度,掌握背后的运作机理依旧有助于更好地把握性能特点,并挑选最适合特定应用场景的技术栈[^3]。 ```rust use tokio::fs::File; use tokio::prelude::*; let mut file = File::open("foo.txt").await?; let mut contents = String::new(); file.read_to_string(&mut contents).await?; println!("文件内容: {}", contents); ``` #### 处理I/O结果的方式 无论哪种编程环境下的异步I/O设计,最终都需要一种有效的手段来接收来自内核态的数据返回值或是状态更新消息。一般情况下,应用程序会注册监听器或者定义回调函数用于捕获这类事件的发生时刻;一旦接收到相应信号便立即着手后续逻辑运算或者是启动新一轮的读写指令序列[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值