Flutter学习笔记-Dart异步编程和原理

本文探讨了Dart如何在单线程环境下实现非阻塞I/O,主要涉及I/O模型(阻塞、非阻塞、IO多路转接、异步IO)、事件循环(Event Loop)机制以及微任务队列。此外,还介绍了Dart中的Isolate用于处理计算密集型任务,提供了一个使用Isolate进行网络请求和模型序列化的例子。
摘要由CSDN通过智能技术生成

对于iOS和Android 原生平台来说,如果要做一个耗时操作,比如网络请求,图片处理等,都会开一个子线程,等待数据处理完成,再在主线程中进行UI的显示和刷新,但是,Dart是一门单线程编程语言。

Dart是如何做到不卡住主线程的呢?

答案就是异步IO+事件循环

I/O模型

注: IO 模型是操作系统层面的,以下代码都是伪代码,只是为了方便理解。

我们先来看看阻塞IO是什么样的:

int count = io.read(buffer); //阻塞等待

当相应线程调用了read之后,它就会一直在那里等着结果返回,什么也不干,这是阻塞式的IO。

但我们的应用程序经常是要同时处理很多个IO的,有人说,这种情况可以使用多线程啊,这确实是个思路,但受制于CPU的实际并发数,每个线程只能同时处理单个IO,性能限制还是很大,而且还要处理不同线程之间的同步问题,程序的复杂度大大增加。

如果进行IO的时候不用阻塞,那情况就不一样了:

while(true){
  for(io in io_array){
      status = io.read(buffer);// 不管有没有数据都立即返回
      if(status == OK){
       
      }
  }
}

有了非阻塞IO,通过轮询的方式,我们就可以对多个IO进行同时处理了,但这样也有一个明显的缺点:在大部分情况下,IO都是没有内容的(CPU的速度远高于IO速度),这样就会导致CPU大部分时间在空转,计算资源依然没有很好得到利用。

为了进一步解决这个问题,人们设计了IO多路转接(IO multiplexing),可以对多个IO监听和设置等待时间:

while(true){
    //如果其中一路IO有数据返回,则立即返回;如果一直没有,最多等待不超过timeout时间
    status = select(io_array, timeout); 
    if(status  == OK){
      for(io in io_array){
          io.read() //立即返回,数据都准备好了
      }
    }
}

有了IO多路转接,CPU资源利用效率又有了一个提升。

在上面的代码中,线程依然是可能会阻塞在 select 上或者产生一些空转的,有没有一个更加完美的方案呢?

答案就是异步IO了:

io.async_read((data) => {
  // dosomething
});

通过异步IO,我们就不用不停问操作系统:你们准备好数据了没?而是一有数据系统就会通过消息或者回调的方式传递给我们。这看起来很完美了,但不幸的是,不是所有的操作系统都很好地支持了这个特性,比如Linux的异步IO就存在各种缺陷,所以在具体的异步IO实现上,很多时候可能会折中考虑不同的IO模式,比如 Node.js 的背后的libeio库,实质上采用线程池与阻塞 I/O 模拟出来的异步 I

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值