## 简介

FFRT: Function Flow Runtime，一种并发编程框架，旨在简化并发编程和任务调度的复杂性。FFRT采用基于任务的调度方式，开发者只需关注任务及其依赖关系，而无需处理底层的线程和计算资源；同时，FFRT采用基于协程的任务执行方式，可以提高任务并行度、提升线程利用率并充分利用多核平台的计算资源，保证系统对所有资源的集约化管理，最终解决系统线程资源滥用问题，打造极致用户体验。

## 模拟器支持情况

本Kit支持模拟器，但与真机存在差异，详情请参见[模拟器与真机的差异](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-emulator-specification)。

## 基本概念

简要说明一下FFRT开发指南中出现或将会出现的一些基本概念：

* **任务 (Task)**: 一种面向开发者的编程线索和面向运行时的执行对象，通常包含一组指令序列及其操作的数据上下文环境。
* **任务依赖 (Task Dependency)**: 任务之间的依赖关系，决定了某个任务是否需要等待其他任务完成才能开始执行。通过任务依赖，开发者可以定义复杂的任务执行顺序。
* **QoS (Quality of Service)**: QoS定义了任务的服务质量等级，用于指示任务的优先级和资源分配。
* **原语 (Primitive)**: 并发编程中的基本操作或构造，用于实现同步和互斥，例如，互斥锁、条件变量等。
* **Worker**: 执行任务的工作线程。每个Worker可以执行多个任务，通常由调度器负责管理和分配任务。
* **调度 (Scheduling)**: 决定任务何时以及由哪个Worker执行的过程。调度器会根据任务的依赖关系和QoS等级等因素进行任务的调度。

### 两种编程模型对比

展开

| 对比项 | 线程编程模型 | 任务编程模型 |
| --- | --- | --- |
| 并行度挖掘方式 | 程序员通过创建多线程并把任务分配到每个线程中执行来挖掘运行时的并行度。 | 程序员（编译器工具或语言特性配合）静态编程时将应用分解成任务及其数据依赖关系，运行时调度器分配任务到工作线程执行。 |
| 谁负责线程创建 | 程序员负责创建线程，线程编程模型无法约束线程的创建，滥用可能造成系统中大量线程。 | FFRT运行时负责工作线程池的创建和管理由调度器负责，程序员无法直接创建线程。 |
| 负载均衡 | 程序员静态编程时将任务映射到线程，映射不合理或任务执行时间不确定造成线程负载不均。 | FFRT运行时根据线程执行状态调度就绪任务到空闲线程执行，减轻了线程负载不均问题。 |
| 调度开销 | 线程调度由内核态调度器完成，调度开销大。 | FFRT运行时在用户态以协程方式调度执行，相比内核线程调度机制更为轻量，减小调度的开销。 |
| 依赖表达 | 线程创建时即处于可执行状态，执行时与其他线程同步操作，增加线程切换。 | FFRT运行时根据任务创建时显式表达的输入依赖和输出依赖关系判断任务可执行状态，当输入依赖不满足时，任务不被调度执行。 |

### FFRT任务编程模型

FFRT编程模型允许开发者通过任务及其依赖关系描述的方式进行应用开发，其主要特性包括Task-Based、Queue-Enabled和Graph-Driven。

**Task-Based特性**

Task-Based指在Function Flow编程模型中开发者以任务方式来组织应用程序表达，运行时以任务粒度执行调度。

FFRT编程模型中的任务包含以下主要特征：

* 任务之间可以直接指定依赖关系，也可以使用通过数据对象表达依赖关系。
* 任务可支持嵌套，即任务在执行过程中可生成新的任务下发给运行时，形成父子任务关系。
* 多任务支持同步，例如等待，锁，条件变量等。

注意

任务颗粒度影响应用执行性能，颗粒度过小增加调度开销，颗粒度过大降低并行度。FFRT编程模型中任务的目标颗粒度最小为100us量级，开发者应注意合理控制任务颗粒度。

**Queue-Enabled特性**

Queue-Enabled指在Function Flow编程模型中开发者可以利用任务队列来约束任务的执行顺序和并发度。任务队列包括串行队列和并发队列，两者具有不同的使用场景：

* 串行队列确保任务按照提交的顺序依次执行，适用于保持特定执行顺序的任务流。
* 并发队列允许多个任务同时执行，提高并发性能，适用于并行计算和高效利用多核处理器。
* 并发队列也可以通过约束某个任务单元的整体并发度，确保系统资源得以合理分配，避免因过度并发导致的性能瓶颈或系统不稳定。

Queue-Enabled特性为开发者提供了灵活的任务调度方式，开发者可以根据具体需求选择合适的任务执行策略，从而优化应用程序的性能。

**Graph-Driven特性**

Graph-Driven指Function Flow编程模型中开发者可以通过构建任务依赖图，来管理任务之间的依赖关系，实现复杂任务流的高效调度。

Function Flow编程模型支持两种方式构建任务依赖图：

* **任务依赖（Task Dependence）**：通过直接描述任务之间依赖关系生成任务依赖图。
* **数据依赖（Data Flow）**：任务之间通过数据的生产者和消费者关系来表达依赖。

开发者可以根据各自业务的特点选择合适的任务依赖图构建方式，从而简化业务模型并降低开发难度。