深入理解Flutter多线程

本文深入探讨Flutter的多线程机制,包括协程概念及其与async/await的关系,Promise的使用,Isolate的实现及代码示例,以及Flutter的Embedder层,阐述了各Runner的角色。文章通过对比iOS线程,解释了Flutter中协程和Isolate如何协同工作,提供更好的并发处理能力。
摘要由CSDN通过智能技术生成

print(‘age $onValue’);
});

协程

如果想要了解asyncawait的原理,就要先了解协程的概念,asyncawait本质上就是协程的一种语法糖。协程,也叫作coroutine,是一种比线程更小的单元。如果从单元大小来说,基本可以理解为进程->线程->协程。

任务调度

在弄懂协程之前,首先要明白并发和并行的概念,并发指的是由系统来管理多个IO的切换,并交由CPU去处理。并行指的是多核CPU在同一时间里执行多个任务。

并发的实现由非阻塞操作+事件通知来完成,事件通知也叫做“中断”。操作过程分为两种,一种是CPU对IO进行操作,在操作完成后发起中断告诉IO操作完成。另一种是IO发起中断,告诉CPU可以进行操作。

线程本质上也是依赖于中断来进行调度的,线程还有一种叫做“阻塞式中断”,就是在执行IO操作时将线程阻塞,等待执行完成后再继续执行。但线程的消耗是很大的,并不适合大量并发操作的处理,而通过单线程并发可以进行大量并发操作。当多核CPU出现后,单个线程就无法很好的利用多核CPU的优势了,所以又引入了线程池的概念,通过线程池来管理大量线程。

协程

在程序执行过程中,离开当前的调用位置有两种方式,继续调用其他函数和return返回离开当前函数。但是执行return时,当前函数在调用栈中的局部变量、形参等状态则会被销毁。

协程分为无线协程和有线协程,无线协程在离开当前调用位置时,会将当前变量放在堆区,当再次回到当前位置时,还会继续从堆区中获取到变量。所以,一般在执行当前函数时就会将变量直接分配到堆区,而asyncawait就属于无线协程的一种。有线协程则会将变量继续保存在栈区,在回到指针指向的离开位置时,会继续从栈中取出调用。

async、await原理

asyncawait为例,协程在执行时,执行到async则表示进入一个协程,会同步执行async的代码块。async的代码块本质上也相当于一个函数,并且有自己的上下文环境。当执行到await时,则表示有任务需要等待,CPU则去调度执行其他IO,也就是后面的代码或其他协程代码。过一段时间CPU就会轮训一次,看某个协程是否任务已经处理完成,有返回结果可以被继续执行,如果可以被继续执行的话,则会沿着上次离开时指针指向的位置继续执行,也就是await标志的位置。

由于并没有开启新的线程,只是进行IO中断改变CPU调度,所以网络请求这样的异步操作可以使用asyncawait,但如果是执行大量耗时同步操作的话,应该使用isolate开辟新的线程去执行。

如果用协程和iOS的dispatch_async进行对比,可以发现二者是比较相似的。从结构定义来看,协程需要将当前await的代码块相关的变量进行存储,dispatch_async也可以通过block来实现临时变量的存储能力。

我之前还在想一个问题,苹果为什么不引入协程的特性呢?后来想了一下,awaitdispatch_async都可以简单理解为异步操作,OC的线程是基于Runloop实现的,Dart本质上也是有事件循环的,而且二者都有自己的事件队列,只是队列数量和分类不同。

我觉得当执行到await时,保存当前的上下文,并将当前位置标记为待处理任务,用一个指针指向当前位置,并将待处理任务放入当前isolate的队列中。在每个事件循环时都去询问这个任务,如果需要进行处理,就

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值