IT评测·应用市场-qidao123.com技术社区

标题: 鸿蒙HarmonyOS APP开辟之FFRT 开辟 [打印本页]

作者: 王國慶    时间: 2024-11-24 08:16
标题: 鸿蒙HarmonyOS APP开辟之FFRT 开辟
场景先容

Function Flow编程模子是一种基于任务和数据驱动的并发编程模子,允许开辟者通过任务及其依靠关系形貌的方式进行应用开辟。FFRT(Function Flow运行时)是支持Function Flow编程模子的软件运行时库,用于调度执行开辟者基于Function Flow编程模子开辟的应用。通过Function Flow编程模子和FFRT,开辟者可专注于应勤奋能开辟,由FFRT在运行时根据任务依靠状态和可用执行资源主动并发调度和执行任务。
本文用于指导开辟者基于Function Flow编程模子和FFRT实现并行编程。
两种编程模子

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

Function Flow 任务编程模子

Function Flow编程模子允许开辟者通过任务及其依靠关系形貌的方式进行应用开辟,其主要特性包括Task-Based 和 Data-Driven 。
Task-Based 特性

Task-Based 指在Function Flow编程模子中开辟者以任务方式来构造应用程序表达,运行时以任务粒度执行调度。
任务定义为一种面向开辟者的编程线索和面向运行时的执行对象,通常包罗一组指令序列及其操作的数据上下文环境。
Function Flow编程模子中的任务包罗以下主要特征:

   留意
任务颗粒度影响应用执行性能,颗粒度过小增加调度开销,颗粒度过大低落并行度。Function Flow编程模子中任务的目的颗粒度最小为100us量级,开辟者应留意合理控制任务颗粒度。
  Data-Driven 特性

Data-Driven指任务之间的依靠关系通过数据依靠表达。
任务执行过程中对其关联的数据对象进行读写操作。在Function Flow编程模子中,数据对象表达抽象为数据签名,每个数据签名唯一对应一个数据对象。
数据依靠抽象为任务所操作的数据对象的数据签名列表,包括输入数据依靠in_deps和输出数据依靠out_deps。数据对象的签名出现在一个任务的in_deps中时,该任务称为数据对象的消费者任务,消费者任务执行不改变其输入数据对象的内容;数据对象的签名出现在任务的out_deps中时,该任务称为数据对象的生产者任务,生产者任务执行改变其输出数据对象的内容,从而生成该数据对象的一个新的版本。
一个数据对象大概存在多个版本,每个版本对应一个生产者任务和零个,一个或多个消费者任务,根据生产者任务和消费者任务的下发次序定义数据对象的多个版本的次序以及每个版本所对应的生产者和消费者任务。
数据依靠解除的任务进入停当状态允许被调度执行,依靠解除状态指任务所有输入数据对象版本的生产者任务执行完成,且所有输出数据对象版本的所有消费者任务执行完成的状态。
通过上述Data-Driven的数据依靠表达,FFRT在运行时可动态构建任务之间的基于生产者/消费者的数据依靠关系并遵循任务数据依靠状态执行调度,包括:

例如,假如有这么一些任务,与数据A的关系表述为:
  1. task1(OUT A);
  2. task2(IN A);
  3. task3(IN A);
  4. task4(OUT A);
  5. task5(OUT A);
复制代码

   为表述方便,本文中的数据流图均以圆圈表现 Task,方块表现数据。
  可以得出以下结论:

接口说明

接口名形貌ffrt_condattr_init (ffrt_condattr_t* attr)初始化条件变量属性。ffrt_condattr_destroy(ffrt_condattr_t* attr)销毁条件变量属性。ffrt_condattr_setclock(ffrt_condattr_t* attr, ffrt_clockid_t clock)设置条件变量的时钟属性。ffrt_condattr_getclock(const ffrt_condattr_t* attr, ffrt_clockid_t* clock)获取条件变量的时钟属性。ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr)初始化条件变量。ffrt_cond_signal(ffrt_cond_t* cond)叫醒阻塞在条件变量上的一个任务。ffrt_cond_broadcast(ffrt_cond_t* cond)叫醒阻塞在条件变量上的所有任务。ffrt_cond_wait(ffrt_cond_t* cond, ffrt_mutex_t* mutex)条件变量等候函数,条件变量不满足时阻塞当前任务。ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point)条件变量超时等候函数,条件变量不满足时阻塞当前任务,超时等候返回。ffrt_cond_destroy(ffrt_cond_t* cond)销毁条件变量。ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr)初始化mutex。ffrt_mutex_lock(ffrt_mutex_t* mutex)获取mutex。ffrt_mutex_unlock(ffrt_mutex_t* mutex)开释mutex。ffrt_mutex_trylock(ffrt_mutex_t* mutex)实验获取mutex。ffrt_mutex_destroy(ffrt_mutex_t* mutex)销毁mutex。ffrt_queue_attr_init(ffrt_queue_attr_t* attr)初始化串行队列属性。ffrt_queue_attr_destroy(ffrt_queue_attr_t* attr)销毁串行队列属性。ffrt_queue_attr_set_qos(ffrt_queue_attr_t* attr, ffrt_qos_t qos)设置串行队列qos属性。ffrt_queue_attr_get_qos(const ffrt_queue_attr_t* attr)获取串行队列qos属性。ffrt_queue_create(ffrt_queue_type_t type, const char* name, const ffrt_queue_attr_t* attr)创建队列。ffrt_queue_destroy(ffrt_queue_t queue)销毁队列。ffrt_queue_submit(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)提交一个任务到队列中调度执行。ffrt_queue_submit_h(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)提交一个任务到队列中调度执行,并返回任务句柄。ffrt_queue_wait(ffrt_task_handle_t handle)等候队列中一个任务执行完成。ffrt_queue_cancel(ffrt_task_handle_t handle)取消队列中一个任务。ffrt_usleep(uint64_t usec)延迟usec微秒。ffrt_yield(void)当前任务主动放权,让其他任务有时机调度执行。ffrt_task_attr_init(ffrt_task_attr_t* attr)初始化任务属性。ffrt_task_attr_set_name(ffrt_task_attr_t* attr, const char* name)设置任务名字。ffrt_task_attr_get_name(const ffrt_task_attr_t* attr)获取任务名字。ffrt_task_attr_destroy(ffrt_task_attr_t* attr)销毁任务属性。ffrt_task_attr_set_qos(ffrt_task_attr_t* attr, ffrt_qos_t qos)设置任务qos。ffrt_task_attr_get_qos(const ffrt_task_attr_t* attr)获取任务qos。ffrt_task_attr_set_delay(ffrt_task_attr_t* attr, uint64_t delay_us)设置任务延迟时间。ffrt_task_attr_get_delay(const ffrt_task_attr_t* attr)获取任务延迟时间。ffrt_this_task_update_qos(ffrt_qos_t qos)更新任务qos。ffrt_this_task_get_id(void)获取任务id。ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_t kind)申请函数执行结构的内存。ffrt_submit_base(ffrt_function_header_t* f, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)提交任务调度执行。ffrt_submit_h_base(ffrt_function_header_t* f, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)提交任务调度执行并返回任务句柄。ffrt_task_handle_destroy(ffrt_task_handle_t handle)销毁任务句柄。ffrt_skip(ffrt_task_handle_t handle)跳过指定任务。ffrt_wait_deps(const ffrt_deps_t* deps)等候依靠的任务完成,当前任务开始执行。 函数先容

任务管理

ffrt_submit_base


声明

  1. const int ffrt_auto_managed_function_storage_size = 64 + sizeof(ffrt_function_header_t);
  2. typedef enum {
  3.     ffrt_function_kind_general,
  4.     ffrt_function_kind_queue
  5. } ffrt_function_kind_t;
  6. void* ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_t kind);
  7. typedef void(*ffrt_function_t)(void*);
  8. typedef struct {
  9.     ffrt_function_t exec;
  10.     ffrt_function_t destroy;
  11.     uint64_t reserve[2];
  12. } ffrt_function_header_t;
  13. void ffrt_submit_base(ffrt_function_header_t* func, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr);
复制代码
参数

kind

func

in_deps

out_deps

attr

返回值


形貌


样例

  1. template<class T>
  2. struct function {
  3.     template<class CT>
  4.     function(ffrt_function_header_t h, CT&& c) : header(h), closure(std::forward<CT>(c)) {}
  5.     ffrt_function_header_t header;
  6.     T closure;
  7. };
  8. template<class T>
  9. void exec_function_wrapper(void* t)
  10. {
  11.     auto f = (function<std::decay_t<T>>*)t;
  12.     f->closure();
  13. }
  14. template<class T>
  15. void destroy_function_wrapper(void* t)
  16. {
  17.     auto f = (function<std::decay_t<T>>*)t;
  18.     f->closure = nullptr;
  19. }
  20. template<class T>
  21. inline ffrt_function_header_t* create_function_wrapper(T&& func)
  22. {
  23.     using function_type = function<std::decay_t<T>>;
  24.     static_assert(sizeof(function_type) <= ffrt_auto_managed_function_storage_size,
  25.         "size of function must be less than ffrt_auto_managed_function_storage_size");
  26.     auto p = ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
  27.     auto f = new (p) function_type(
  28.         {exec_function_wrapper<T>, destroy_function_wrapper<T>},
  29.         std::forward<T>(func));
  30.     return (ffrt_function_header_t*)f;
  31. }
  32. static inline void submit(std::function<void()>&& func)
  33. {
  34.     return ffrt_submit_base(create_function_wrapper(std::move(func)), NULL, NULL, NULL);
  35. }
复制代码
ffrt_wait



声明

  1. void ffrt_wait_deps(ffrt_deps_t* deps);
  2. void ffrt_wait();
复制代码
参数

deps

返回值


形貌


样例

recursive fibonacci
串行版的fibonacci 可以实现为:
  1. #include <stdio.h>
  2. void fib(int x, int* y) {
  3.     if (x <= 1) {
  4.         *y = x;
  5.     } else {
  6.         int y1, y2;
  7.         fib(x - 1, &y1);
  8.         fib(x - 2, &y2);
  9.         *y = y1 + y2;
  10.     }
  11. }
  12. int main(int narg, char** argv)
  13. {
  14.     int r;
  15.     fib(10, &r);
  16.     printf("fibonacci 10: %d\n", r);
  17.     return 0;
  18. }
复制代码
若要使用 FFRT 实现并行(注,对于单纯的fibonacci,单个 Task 的计算量极小,不具有并行加速的意义,但这种调用pattern 对并行编程模子的机动性磨练黑白常高的),其中1种可行的实现为:
  1. #include <stdio.h>
  2. #include "ffrt.h"  //包含所有ffrt涉及的头文件
  3. typedef struct {
  4.     int x;
  5.     int* y;
  6. } fib_ffrt_s;
  7. typedef struct {
  8.     ffrt_function_header_t header;
  9.     ffrt_function_t func;
  10.     ffrt_function_t after_func;
  11.     void* arg;
  12. } c_function;
  13. static void ffrt_exec_function_wrapper(void* t)
  14. {
  15.     c_function* f = (c_function*)t;
  16.     if (f->func) {
  17.         f->func(f->arg);
  18.     }
  19. }
  20. static void ffrt_destroy_function_wrapper(void* t)
  21. {
  22.     c_function* f = (c_function*)t;
  23.     if (f->after_func) {
  24.         f->after_func(f->arg);
  25.     }
  26. }
  27. #define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
  28. static inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
  29.     const ffrt_function_t after_func, void* arg)
  30. {
  31.     FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
  32.         size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
  33.     c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
  34.     f->header.exec = ffrt_exec_function_wrapper;
  35.     f->header.destroy = ffrt_destroy_function_wrapper;
  36.     f->func = func;
  37.     f->after_func = after_func;
  38.     f->arg = arg;
  39.     return (ffrt_function_header_t*)f;
  40. }
  41. static inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
  42.     void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
  43. {
  44.     ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
  45. }
  46. #define ffrt_deps_define(name, dep1, ...) const void* __v_##name[] = {dep1, ##__VA_ARGS__}; \
  47.     ffrt_deps_t name = {sizeof(__v_##name) / sizeof(void*), __v_##name}
  48. void fib_ffrt(void* arg)
  49. {
  50.     fib_ffrt_s* p = (fib_ffrt_s*)arg;
  51.     int x = p->x;
  52.     int* y = p->y;
  53.     if (x <= 1) {
  54.         *y = x;
  55.     } else {
  56.         int y1, y2;
  57.         fib_ffrt_s s1 = {x - 1, &y1};
  58.         fib_ffrt_s s2 = {x - 2, &y2};
  59.         ffrt_deps_define(dx, &x);
  60.         ffrt_deps_define(dy1, &y1);
  61.         ffrt_deps_define(dy2, &y2);
  62.         ffrt_deps_define(dy12, &y1, &y2);
  63.         ffrt_submit_c(fib_ffrt, NULL, &s1, &dx, &dy1, NULL);
  64.         ffrt_submit_c(fib_ffrt, NULL, &s2, &dx, &dy2, NULL);
  65.         ffrt_wait_deps(&dy12);
  66.         *y = y1 + y2;
  67.     }
  68. }
  69. int main(int narg, char** argv)
  70. {
  71.     int r;
  72.     fib_ffrt_s s = {10, &r};
  73.     ffrt_deps_define(dr, &r);
  74.     ffrt_submit_c(fib_ffrt, NULL, &s, NULL, &dr, NULL);
  75.     ffrt_wait_deps(&dr);
  76.     printf("fibonacci 10: %d\n", r);
  77.     return 0;
  78. }
复制代码
解析:

   以上实现,因为必要用户显式管理数据生命周期和函数入参打包两个因素,以是使得代码实现非常复杂。
  ffrt_deps_t


声明

  1. typedef enum {
  2.     ffrt_dependence_data,
  3.     ffrt_dependence_task,
  4. } ffrt_dependence_type_t;
  5. typedef struct {
  6.     ffrt_dependence_type_t type;
  7.     const void* ptr;
  8. } ffrt_dependence_t;
  9. typedef struct {
  10.     uint32_t len;
  11.     const ffrt_dependence_t* items;
  12. } ffrt_deps_t;
复制代码
参数

len

item

type

ptr

返回值


形貌


样例


  1. // 创建数据依赖的ffrt_deps_t
  2. int x = 0;
  3. const std::vector<ffrt_dependence_t> in_deps = {{ffrt_dependence_data, &x}};
  4. ffrt_deps_t in{static_cast<uint32_t>(in_deps.size()), in_deps.data()};
  5. // 提交某个返回handle任务
  6. ffrt_task_handle_t task = ffrt_submit_h_base(
  7.         ffrt_create_function_wrapper(OnePlusForTest, NULL, &a), NULL, NULL, &attr);
  8. // 创建任务依赖的ffrt_deps_t
  9. const std::vector<ffrt_dependence_t> wait_deps = {{ffrt_dependence_task, task}};
  10. ffrt_deps_t wait{static_cast<uint32_t>(wait_deps.size()), wait_deps.data()};
复制代码
ffrt_task_attr_t



声明

  1. typedef enum {
  2.     ffrt_qos_inherent = -1,
  3.     ffrt_qos_background,
  4.     ffrt_qos_utility,
  5.     ffrt_qos_default,
  6.     ffrt_qos_user_initiated,
  7. } ffrt_qos_default_t;
  8. typedef int ffrt_qos_t;
  9. typedef struct {
  10.     uint32_t storage[(ffrt_task_attr_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
  11. } ffrt_task_attr_t;
  12. typedef void* ffrt_task_handle_t;
  13. int ffrt_task_attr_init(ffrt_task_attr_t* attr);
  14. void ffrt_task_attr_destroy(ffrt_task_attr_t* attr);
  15. void ffrt_task_attr_set_qos(ffrt_task_attr_t* attr, ffrt_qos_t qos);
  16. ffrt_qos_t ffrt_task_attr_get_qos(const ffrt_task_attr_t* attr);
  17. void ffrt_task_attr_set_name(ffrt_task_attr_t* attr, const char* name);
  18. const char* ffrt_task_attr_get_name(const ffrt_task_attr_t* attr);
  19. void ffrt_task_attr_set_delay(ffrt_task_attr_t* attr, uint64_t delay_us);
  20. uint64_t ffrt_task_attr_get_delay(const ffrt_task_attr_t* attr);
复制代码
参数

attr

qos

delay_us

返回值


形貌


样例


  1. #include <stdio.h>
  2. #include "ffrt.h"
  3. void my_print(void* arg)
  4. {
  5.     printf("hello ffrt\n");
  6. }
  7. typedef struct {
  8.     ffrt_function_header_t header;
  9.     ffrt_function_t func;
  10.     ffrt_function_t after_func;
  11.     void* arg;
  12. } c_function;
  13. static void ffrt_exec_function_wrapper(void* t)
  14. {
  15.     c_function* f = (c_function*)t;
  16.     if (f->func) {
  17.         f->func(f->arg);
  18.     }
  19. }
  20. static void ffrt_destroy_function_wrapper(void* t)
  21. {
  22.     c_function* f = (c_function*)t;
  23.     if (f->after_func) {
  24.         f->after_func(f->arg);
  25.     }
  26. }
  27. #define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
  28. static inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
  29.     const ffrt_function_t after_func, void* arg)
  30. {
  31.     FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
  32.         size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
  33.     c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
  34.     f->header.exec = ffrt_exec_function_wrapper;
  35.     f->header.destroy = ffrt_destroy_function_wrapper;
  36.     f->func = func;
  37.     f->after_func = after_func;
  38.     f->arg = arg;
  39.     return (ffrt_function_header_t*)f;
  40. }
  41. static inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
  42.     void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
  43. {
  44.     ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
  45. }
  46. int main(int narg, char** argv)
  47. {
  48.     ffrt_task_attr_t attr;
  49.     ffrt_task_attr_init(&attr);
  50.     ffrt_task_attr_set_qos(&attr, ffrt_qos_background);
  51.     ffrt_task_attr_set_delay(&attr, 10000);
  52.     ffrt_submit_c(my_print, NULL, NULL, NULL, NULL, &attr);
  53.     ffrt_task_attr_destroy(&attr);
  54.     ffrt_wait();
  55.     return 0;
  56. }
复制代码
ffrt_submit_h_base



声明

  1. typedef void* ffrt_task_handle_t;
  2. ffrt_task_handle_t ffrt_submit_h_base(ffrt_function_t func, void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr);
  3. void ffrt_task_handle_destroy(ffrt_task_handle_t handle);
复制代码
参数

func

in_deps

out_deps

attr

返回值


形貌


样例

  1. #include <stdio.h>
  2. #include "ffrt.h"
  3. void func0(void* arg)
  4. {
  5.     printf("hello ");
  6. }
  7. void func1(void* arg)
  8. {
  9.     (*(int*)arg)++;
  10. }
  11. void func2(void* arg)
  12. {
  13.     printf("world, x = %d\n", *(int*)arg);
  14. }
  15. void func3(void* arg)
  16. {
  17.     printf("handle wait");
  18.     (*(int*)arg)++;
  19. }
  20. typedef struct {
  21.     ffrt_function_header_t header;
  22.     ffrt_function_t func;
  23.     ffrt_function_t after_func;
  24.     void* arg;
  25. } c_function;
  26. static void ffrt_exec_function_wrapper(void* t)
  27. {
  28.     c_function* f = (c_function*)t;
  29.     if (f->func) {
  30.         f->func(f->arg);
  31.     }
  32. }
  33. static void ffrt_destroy_function_wrapper(void* t)
  34. {
  35.     c_function* f = (c_function*)t;
  36.     if (f->after_func) {
  37.         f->after_func(f->arg);
  38.     }
  39. }
  40. #define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
  41. static inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
  42.     const ffrt_function_t after_func, void* arg)
  43. {
  44.     FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
  45.         size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
  46.     c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
  47.     f->header.exec = ffrt_exec_function_wrapper;
  48.     f->header.destroy = ffrt_destroy_function_wrapper;
  49.     f->func = func;
  50.     f->after_func = after_func;
  51.     f->arg = arg;
  52.     return (ffrt_function_header_t*)f;
  53. }
  54. static inline ffrt_task_handle_t ffrt_submit_h_c(ffrt_function_t func, const ffrt_function_t after_func,
  55.     void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
  56. {
  57.     return ffrt_submit_h_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
  58. }
  59. static inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
  60.     void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
  61. {
  62.     ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
  63. }
  64. int main(int narg, char** argv)
  65. {  
  66.     // handle work with submit
  67.     ffrt_task_handle_t h = ffrt_submit_h_c(func0, NULL, NULL, NULL, NULL, NULL); // not need some data in this task
  68.     int x = 1;
  69.     const std::vector<ffrt_dependence_t> in_deps = {{ffrt_dependence_data, &x}};
  70.     ffrt_deps_t d2{static_cast<uint32_t>(in_deps.size()), in_deps.data()};
  71.     const std::vector<ffrt_dependence_t> out_deps = {{ffrt_dependence_data, &x}};
  72.     ffrt_deps_t d1{static_cast<uint32_t>(out_deps.size()), out_deps.data()};
  73.     ffrt_submit_c(func1, NULL, &x, NULL, &d1, NULL);
  74.     ffrt_submit_c(func2, NULL, &x, &d2, NULL, NULL); // this task depend x and h
  75.     ffrt_task_handle_destroy(h);
  76.    
  77.     // handle work with wait
  78.     ffrt_task_handle_t h2 = ffrt_submit_h_c(func3, NULL, &x, NULL, NULL, NULL);
  79.     const std::vector<ffrt_dependence_t> wait_deps = {{ffrt_dependence_task, h2}};
  80.     ffrt_deps_t d3{static_cast<uint32_t>(wait_deps.size()), wait_deps.data()};
  81.     ffrt_wait_deps(&d3);
  82.     ffrt_task_handle_destroy(h2);
  83.     printf("x = %d", x);
  84.     ffrt_wait();
  85.     return 0;
  86. }
复制代码

  1. hello world, x = 2
  2. handle wait
  3. x = 3
复制代码
ffrt_this_task_get_id



声明

  1. uint64_t ffrt_this_task_get_id();
复制代码
参数


返回值


形貌


样例


ffrt_this_task_update_qos



声明

  1. int ffrt_this_task_update_qos(ffrt_qos_t qos);
复制代码
参数


返回值


形貌


样例


串行队列



ffrt_queue_attr_t

声明

  1. typedef struct {
  2.     uint32_t storage[(ffrt_queue_attr_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
  3. } ffrt_queue_attr_t;
  4. int ffrt_queue_attr_init(ffrt_queue_attr_t* attr);
  5. void ffrt_queue_attr_destroy(ffrt_queue_attr_t* attr);
复制代码
参数

attr

返回值


形貌


样例

参考ffrt_queue_t章节的样例。
ffrt_queue_t

声明

  1. typedef enum { ffrt_queue_serial, ffrt_queue_max } ffrt_queue_type_t;
  2. typedef void* ffrt_queue_t;
  3. ffrt_queue_t ffrt_queue_create(ffrt_queue_type_t type, const char* name, const ffrt_queue_attr_t* attr)
  4. void ffrt_queue_destroy(ffrt_queue_t queue)
复制代码
参数

type

name

attr

返回值


形貌


样例

  1. #include <stdio.h>
  2. #include "ffrt.h"
  3. using namespace std;
  4. template<class T>
  5. struct Function {
  6.     template<class CT>
  7.     Function(ffrt_function_header_t h, CT&& c) : header(h), closure(std::forward<CT>(c)) {}
  8.     ffrt_function_header_t header;
  9.     T closure;
  10. };
  11. template<class T>
  12. void ExecFunctionWrapper(void* t)
  13. {
  14.     auto f = reinterpret_cast<Function<std::decay_t<T>>*>(t);
  15.     f->closure();
  16. }
  17. template<class T>
  18. void DestroyFunctionWrapper(void* t)
  19. {
  20.     auto f = reinterpret_cast<Function<std::decay_t<T>>*>(t);
  21.     f->closure = nullptr;
  22. }
  23. template<class T>
  24. static inline ffrt_function_header_t* create_function_wrapper(T&& func,
  25.     ffrt_function_kind_t kind = ffrt_function_kind_general)
  26. {
  27.     using function_type = Function<std::decay_t<T>>;
  28.     auto p = ffrt_alloc_auto_managed_function_storage_base(kind);
  29.     auto f =
  30.         new (p)function_type({ ExecFunctionWrapper<T>, DestroyFunctionWrapper<T>, { 0 } }, std::forward<T>(func));
  31.     return reinterpret_cast<ffrt_function_header_t*>(f);
  32. }
  33. int main(int narg, char** argv)
  34. {
  35.     ffrt_queue_attr_t queue_attr;
  36.     (void)ffrt_queue_attr_init(&queue_attr);
  37.     ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
  38.     ffrt_queue_submit(queue_handle, create_function_wrapper([]() {printf("Task done.\n");}, ffrt_function_kind_queue), nullptr);
  39.     ffrt_queue_attr_destroy(&queue_attr);
  40.     ffrt_queue_destroy(queue_handle);
  41. }
复制代码
同步原语

ffrt_mutex_t



声明

  1. typedef enum {
  2.     ffrt_error = -1,
  3.     ffrt_success = 0,
  4.     ffrt_error_nomem = ENOMEM,
  5.     ffrt_error_timedout = ETIMEDOUT,
  6.     ffrt_error_busy = EBUSY,
  7.     ffrt_error_inval = EINVAL
  8. } ffrt_error_t;
  9. struct ffrt_mutex_t;
  10. int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr);
  11. int ffrt_mutex_lock(ffrt_mutex_t* mutex);
  12. int ffrt_mutex_unlock(ffrt_mutex_t* mutex);
  13. int ffrt_mutex_trylock(ffrt_mutex_t* mutex);
  14. int ffrt_mutex_destroy(ffrt_mutex_t* mutex);
复制代码
参数

attr

mutex

返回值


形貌


样例

  1. #include <stdio.h>
  2. #include "ffrt.h"
  3. typedef struct {
  4.     int* sum;
  5.     ffrt_mutex_t* mtx;
  6. } tuple;
  7. void func(void* arg)
  8. {
  9.     tuple* t = (tuple*)arg;
  10.    
  11.     int ret = ffrt_mutex_lock(t->mtx);
  12.     if (ret != ffrt_success) {
  13.         printf("error\n");
  14.     }
  15.     (*t->sum)++;
  16.     ret = ffrt_mutex_unlock(t->mtx);
  17.     if (ret != ffrt_success) {
  18.         printf("error\n");
  19.     }
  20. }
  21. typedef struct {
  22.     ffrt_function_header_t header;
  23.     ffrt_function_t func;
  24.     ffrt_function_t after_func;
  25.     void* arg;
  26. } c_function;
  27. static void ffrt_exec_function_wrapper(void* t)
  28. {
  29.     c_function* f = (c_function*)t;
  30.     if (f->func) {
  31.         f->func(f->arg);
  32.     }
  33. }
  34. static void ffrt_destroy_function_wrapper(void* t)
  35. {
  36.     c_function* f = (c_function*)t;
  37.     if (f->after_func) {
  38.         f->after_func(f->arg);
  39.     }
  40. }
  41. #define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
  42. static inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
  43.     const ffrt_function_t after_func, void* arg)
  44. {
  45.     FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
  46.         size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
  47.     c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
  48.     f->header.exec = ffrt_exec_function_wrapper;
  49.     f->header.destroy = ffrt_destroy_function_wrapper;
  50.     f->func = func;
  51.     f->after_func = after_func;
  52.     f->arg = arg;
  53.     return (ffrt_function_header_t*)f;
  54. }
  55. static inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
  56.     void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
  57. {
  58.     ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
  59. }
  60. void ffrt_mutex_task()
  61. {
  62.     int sum = 0;
  63.     ffrt_mutex_t mtx;
  64.     tuple t = {&sum, &mtx};
  65.     int ret = ffrt_mutex_init(&mtx, NULL);
  66.     if (ret != ffrt_success) {
  67.         printf("error\n");
  68.     }
  69.     for (int i = 0; i < 10; i++) {
  70.         ffrt_submit_c(func, NULL, &t, NULL, NULL, NULL);
  71.     }
  72.     ffrt_mutex_destroy(&mtx);
  73.     ffrt_wait();
  74.     printf("sum = %d", sum);
  75. }
  76. int main(int narg, char** argv)
  77. {
  78.     int r;
  79.     ffrt_submit_c(ffrt_mutex_task, NULL, NULL, NULL, NULL, NULL);
  80.     ffrt_wait();
  81.     return 0;
  82. }
复制代码
预期输出为:
  1. sum=10
复制代码

ffrt_cond_t



声明

  1. typedef enum {
  2.     ffrt_error = -1,
  3.     ffrt_success = 0,
  4.     ffrt_error_nomem = ENOMEM,
  5.     ffrt_error_timedout = ETIMEDOUT,
  6.     ffrt_error_busy = EBUSY,
  7.     ffrt_error_inval = EINVAL
  8. } ffrt_error_t;
  9. struct ffrt_cond_t;
  10. int ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr);
  11. int ffrt_cond_signal(ffrt_cond_t* cond);
  12. int ffrt_cond_broadcast(ffrt_cond_t* cond);
  13. int ffrt_cond_wait(ffrt_cond_t*cond, ffrt_mutex_t* mutex);
  14. int ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point);
  15. int ffrt_cond_destroy(ffrt_cond_t* cond);
复制代码
参数

cond

attr

mutex

time_point

返回值


形貌


样例

  1. #include <stdio.h>
  2. #include "ffrt.h"
  3. typedef struct {
  4.     ffrt_cond_t* cond;
  5.     int* a;
  6.     ffrt_mutex_t* lock_;
  7. } tuple;
  8. void func1(void* arg)
  9. {
  10.     tuple* t = (tuple*)arg;
  11.     int ret = ffrt_mutex_lock(t->lock_);
  12.     if (ret != ffrt_success) {
  13.         printf("error\n");
  14.     }
  15.     while (*t->a != 1) {
  16.         ret = ffrt_cond_wait(t->cond, t->lock_);
  17.         if (ret != ffrt_success) {
  18.             printf("error\n");
  19.         }
  20.     }
  21.     ret = ffrt_mutex_unlock(t->lock_);
  22.     if (ret != ffrt_success) {
  23.         printf("error\n");
  24.     }
  25.     printf("a = %d", *(t->a));
  26. }
  27. void func2(void* arg)
  28. {
  29.     tuple* t = (tuple*)arg;
  30.     int ret = ffrt_mutex_lock(t->lock_);
  31.     if (ret != ffrt_success) {
  32.         printf("error\n");
  33.     }
  34.     *(t->a) = 1;
  35.     ret = ffrt_cond_signal(t->cond);
  36.     if (ret != ffrt_success) {
  37.         printf("error\n");
  38.     }
  39.     ret = ffrt_mutex_unlock(t->lock_);
  40.     if (ret != ffrt_success) {
  41.         printf("error\n");
  42.     }
  43. }
  44. typedef struct {
  45.     ffrt_function_header_t header;
  46.     ffrt_function_t func;
  47.     ffrt_function_t after_func;
  48.     void* arg;
  49. } c_function;
  50. static void ffrt_exec_function_wrapper(void* t)
  51. {
  52.     c_function* f = (c_function*)t;
  53.     if (f->func) {
  54.         f->func(f->arg);
  55.     }
  56. }
  57. static void ffrt_destroy_function_wrapper(void* t)
  58. {
  59.     c_function* f = (c_function*)t;
  60.     if (f->after_func) {
  61.         f->after_func(f->arg);
  62.     }
  63. }
  64. #define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
  65. static inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
  66.     const ffrt_function_t after_func, void* arg)
  67. {
  68.     FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
  69.         size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
  70.     c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
  71.     f->header.exec = ffrt_exec_function_wrapper;
  72.     f->header.destroy = ffrt_destroy_function_wrapper;
  73.     f->func = func;
  74.     f->after_func = after_func;
  75.     f->arg = arg;
  76.     return (ffrt_function_header_t*)f;
  77. }
  78. static inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
  79.     void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
  80. {
  81.     ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
  82. }
  83. void ffrt_cv_task()
  84. {
  85.     ffrt_cond_t cond;
  86.     int ret = ffrt_cond_init(&cond, NULL);
  87.     if (ret != ffrt_success) {
  88.         printf("error\n");
  89.     }
  90.     int a = 0;
  91.     ffrt_mutex_t lock_;
  92.     tuple t = {&cond, &a, &lock_};
  93.     ret = ffrt_mutex_init(&lock_, NULL);
  94.     if (ret != ffrt_success) {
  95.         printf("error\n");
  96.     }
  97.     ffrt_submit_c(func1, NULL, &t, NULL, NULL, NULL);
  98.     ffrt_submit_c(func2, NULL, &t, NULL, NULL, NULL);
  99.     ffrt_wait();
  100.     ffrt_cond_destroy(&cond);
  101.     ffrt_mutex_destroy(&lock_);
  102. }
  103. int main(int narg, char** argv)
  104. {
  105.     ffrt_submit_c(ffrt_cv_task, NULL, NULL, NULL, NULL, NULL);
  106.     ffrt_wait();
  107.     return 0;
  108. }
复制代码
预期输出为:
  1. a=1
复制代码

杂项

ffrt_usleep



声明

  1. int ffrt_usleep(uint64_t usec);
复制代码
参数

usec

返回值


形貌


样例

  1. #include <time.h>
  2. #include <stdio.h>
  3. #include "ffrt.h"
  4. void func(void* arg)
  5. {
  6.     printf("Time: %s", ctime(&(time_t){time(NULL)}));
  7.     ffrt_usleep(2000000); // 睡眠 2 秒
  8.     printf("Time: %s", ctime(&(time_t){time(NULL)}));
  9. }
  10. typedef struct {
  11.     ffrt_function_header_t header;
  12.     ffrt_function_t func;
  13.     ffrt_function_t after_func;
  14.     void* arg;
  15. } c_function;
  16. static void ffrt_exec_function_wrapper(void* t)
  17. {
  18.     c_function* f = (c_function*)t;
  19.     if (f->func) {
  20.         f->func(f->arg);
  21.     }
  22. }
  23. static void ffrt_destroy_function_wrapper(void* t)
  24. {
  25.     c_function* f = (c_function*)t;
  26.     if (f->after_func) {
  27.         f->after_func(f->arg);
  28.     }
  29. }
  30. #define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
  31. static inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
  32.     const ffrt_function_t after_func, void* arg)
  33. {
  34.     FFRT_STATIC_ASSERT(sizeof(c_function) <= ffrt_auto_managed_function_storage_size,
  35.         size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
  36.     c_function* f = (c_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
  37.     f->header.exec = ffrt_exec_function_wrapper;
  38.     f->header.destroy = ffrt_destroy_function_wrapper;
  39.     f->func = func;
  40.     f->after_func = after_func;
  41.     f->arg = arg;
  42.     return (ffrt_function_header_t*)f;
  43. }
  44. static inline void ffrt_submit_c(ffrt_function_t func, const ffrt_function_t after_func,
  45.     void* arg, const ffrt_deps_t* in_deps, const ffrt_deps_t* out_deps, const ffrt_task_attr_t* attr)
  46. {
  47.     ffrt_submit_base(ffrt_create_function_wrapper(func, after_func, arg), in_deps, out_deps, attr);
  48. }
  49. int main(int narg, char** argv)
  50. {
  51.     ffrt_submit_c(func, NULL, NULL, NULL, NULL, NULL);
  52.     ffrt_wait();
  53.     return 0;
  54. }
复制代码
ffrt_yield



声明

  1. void ffrt_yield();
复制代码
参数


返回值


形貌


样例


开辟步骤

以下步骤形貌了怎样使用FFRT提供的Native API接口,创建并行任务和串行队列任务以及销毁相应资源。
添加动态链接库
CMakeLists.txt中添加以下lib:
  1. libffrt.z.so
复制代码
头文件
  1. #include "ffrt/task.h"
  2. #include "ffrt/type_def.h"
  3. #include "ffrt/condition_variable.h"
  4. #include "ffrt/mutex.h"
  5. #include "ffrt/queue.h"
  6. #include "ffrt/sleep.h"
复制代码
  1. // 第一种使用模板,支持C++
  2. template<class T>
  3. struct Function {
  4.     template<class CT>
  5.     Function(ffrt_function_header_t h, CT&& c) : header(h), closure(std::forward<CT>(c)) {}
  6.     ffrt_function_header_t header;
  7.     T closure;
  8. };
  9. template<class T>
  10. void ExecFunctionWrapper(void* t)
  11. {
  12.     auto f = reinterpret_cast<Function<std::decay_t<T>>*>(t);
  13.     f->closure();
  14. }
  15. template<class T>
  16. void DestroyFunctionWrapper(void* t)
  17. {
  18.     auto f = reinterpret_cast<Function<std::decay_t<T>>*>(t);
  19.     f->closure = nullptr;
  20. }
  21. template<class T>
  22. static inline ffrt_function_header_t* create_function_wrapper(T&& func,
  23.     ffrt_function_kind_t kind = ffrt_function_kind_general)
  24. {
  25.     using function_type = Function<std::decay_t<T>>;
  26.     auto p = ffrt_alloc_auto_managed_function_storage_base(kind);
  27.     auto f =
  28.         new (p)function_type({ ExecFunctionWrapper<T>, DestroyFunctionWrapper<T>, { 0 } }, std::forward<T>(func));
  29.     return reinterpret_cast<ffrt_function_header_t*>(f);
  30. }
  31. // 第二种创建方式
  32. typedef struct {
  33.     ffrt_function_header_t header;
  34.     ffrt_function_t func;
  35.     ffrt_function_t after_func;
  36.     void* arg;
  37. } CFunction;
  38. static void FfrtExecFunctionWrapper(void* t)
  39. {
  40.     CFunction* f = static_cast<CFunction*>(t);
  41.     if (f->func) {
  42.         f->func(f->arg);
  43.     }
  44. }
  45. static void FfrtDestroyFunctionWrapper(void* t)
  46. {
  47.     CFunction* f = static_cast<CFunction*>(t);
  48.     if (f->after_func) {
  49.         f->after_func(f->arg);
  50.     }
  51. }
  52. #define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
  53. static inline ffrt_function_header_t* ffrt_create_function_wrapper(const ffrt_function_t func,
  54.     const ffrt_function_t after_func, void* arg, ffrt_function_kind_t kind_t = ffrt_function_kind_general)
  55. {
  56.     FFRT_STATIC_ASSERT(sizeof(CFunction) <= ffrt_auto_managed_function_storage_size,
  57.         size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);
  58.     CFunction* f = static_cast<CFunction*>(ffrt_alloc_auto_managed_function_storage_base(kind_t));
  59.     f->header.exec = FfrtExecFunctionWrapper;
  60.     f->header.destroy = FfrtDestroyFunctionWrapper;
  61.     f->func = func;
  62.     f->after_func = after_func;
  63.     f->arg = arg;
  64.     return reinterpret_cast<ffrt_function_header_t*>(f);
  65. }
  66. // 样例:待提交执行的函数
  67. void OnePlusForTest(void* arg)
  68. {
  69.     (*static_cast<int*>(arg)) += 1;
  70. }
复制代码
用户提交任务时可以设置任务属性,包括qos优先级,名称等,详细可参考接口文档。
  1. // ******初始化并行任务属性******
  2. ffrt_task_attr_t attr;
  3. ffrt_task_attr_init(&attr);
  4. // ******创建串行队列******
  5. // 创建串行队列的属性
  6. ffrt_queue_attr_t queue_attr;
  7. // 创建串行队列的handle
  8. ffrt_queue_t queue_handle;
  9. // 初始化队列属性
  10. (void)ffrt_queue_attr_init(&queue_attr);
  11. // 如有需要,设置指定优先级
  12. ffrt_queue_attr_set_qos(&queue_attr, static_cast<ffrt_qos_t>(ffrt_qos_inherit));
  13. // 如有需要,设置超时时间(ms)
  14. ffrt_queue_attr_set_timeout(&queue_attr, 10000);
  15. // 如有需要,设置超时回调
  16. int x = 0;
  17. ffrt_queue_attr_set_callback(&queue_attr, ffrt_create_function_wrapper(OnePlusForTest, NULL, &x,
  18.     ffrt_function_kind_queue));
  19. // 基于属性,初始化队列
  20. queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
复制代码
  1. int a = 0;
  2. // ******并行任务******
  3. // 提交不带handle返回值的并行任务
  4. ffrt_submit_base(ffrt_create_function_wrapper(OnePlusForTest, NULL, &a), NULL, NULL, &attr);
  5. // 提交带handle返回值的并行任务
  6. ffrt_task_handle_t task = ffrt_submit_h_base(
  7.     ffrt_create_function_wrapper(OnePlusForTest, NULL, &a), NULL, NULL, &attr);
  8. // ******串行任务******
  9. // 提交不返回handle的串行队列任务
  10. ffrt_queue_submit(queue_handle, ffrt_create_function_wrapper(OnePlusForTest, nullptr, &a,
  11.     ffrt_function_kind_queue), nullptr);
  12. // 提交带handle的串行队列任务
  13. ffrt_task_handle_t handle = ffrt_queue_submit_h(queue_handle,
  14.     ffrt_create_function_wrapper(OnePlusForTest, nullptr, &a, ffrt_function_kind_queue), nullptr);
  15. // 如果需要等待执行结果,则调用wait
  16. const std::vector<ffrt_dependence_t> wait_deps = {{ffrt_dependence_task, task}};
  17. ffrt_deps_t wait{static_cast<uint32_t>(wait_deps.size()), wait_deps.data()};
  18. ffrt_wait_deps(&wait);
  19. ffrt_queue_wait(handle);
复制代码
  1. // ******销毁并行任务******
  2. ffrt_task_attr_destroy(&attr);
  3. ffrt_task_handle_destroy(task);
  4. // ******销毁串行队列任务******
  5. // 先销毁任务handle,再销毁队列
  6. ffrt_queue_attr_destroy(&queue_attr);
  7. ffrt_task_handle_destroy(handle);
  8. ffrt_queue_destroy(queue_handle);
复制代码
使用建议

建议1: 函数化

根本思想:计算过程函数化

   做到纯函数的利益在于:1. 能够最大化发掘并行度,2.避免DataRace和锁的问题。
  在实际中,可以根据场景放松纯函数的约束,但条件是:

建议2: 使用FFRT提供的替代API


建议3: Deadline机制


建议4: 从线程模子迁移


已知限制

C API中初始化ffrt对象后,对象的置空与销毁由用户负责


  1. #include "ffrt.h"
  2. void abnormal_case_1()
  3. {
  4.     ffrt_task_handle_t h = ffrt_submit_h_base([](){printf("Test task running...\n");}, NULL, NULL, NULL, NULL, NULL);
  5.     ...
  6.     ffrt_task_handle_destroy(h);
  7.     ffrt_task_handle_destroy(h); // double free
  8. }
复制代码

  1. #include "ffrt.h"
  2. void abnormal_case_2()
  3. {
  4.     ffrt_task_handle_t h = ffrt_submit_h_base([](){printf("Test task running...\n");}, NULL, NULL, NULL, NULL, NULL);
  5.     ...
  6.     // memory leak
  7. }
复制代码

  1. #include "ffrt.h"
  2. void normal_case()
  3. {
  4.     ffrt_task_handle_t h = ffrt_submit_h_base([](){printf("Test task running...\n");}, NULL, NULL, NULL, NULL, NULL);
  5.     ...
  6.     ffrt_task_handle_destroy(h);
  7.     h = nullptr; // if necessary
  8. }
复制代码
总是有很多小伙伴反馈说:鸿蒙开辟不知道学习哪些技术?不知道必要重点把握哪些鸿蒙应用开辟知识点? 为了办理大家这些学习烦恼。在这预备了一份很实用的鸿蒙(HarmonyOS NEXT)学习路线与学习文档给大家用来跟着学习。
针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开辟技术的学习路线,包罗了鸿蒙开辟必把握的核心知识要点,内容有(ArkTS、ArkUI开辟组件、Stage模子、多端摆设、分布式应用开辟、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开辟、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

《鸿蒙 (Harmony OS)开辟学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN

怎样快速入门?

1.根本概念
2.构建第一个ArkTS应用
3.……


开辟基础知识

1.应用基础知识
2.设置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

基于ArkTS 开辟

1.Ability开辟
2.UI开辟
3.公共事件与关照
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.装备管理
12.装备使用信息统计
13.DFX
14.国际化开辟
15.折叠屏系列
16.……

鸿蒙开辟面试真题(含参考答案):https://gitcode.com/HarmonyOS_MN


OpenHarmony 开辟环境搭建:https://gitcode.com/HarmonyOS_MN



《OpenHarmony源码解析》:https://gitcode.com/HarmonyOS_MN

搭建开辟环境
系统架构分析


OpenHarmony 装备开辟学习手册:https://gitcode.com/HarmonyOS_MN




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4