• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Function Flow Runtime C API
2
3## 任务管理
4
5### ffrt_deps_t
6
7#### 声明
8
9```c
10typedef enum {
11    ffrt_dependence_data,
12    ffrt_dependence_task,
13} ffrt_dependence_type_t;
14
15typedef struct {
16    ffrt_dependence_type_t type;
17    const void* ptr;
18} ffrt_dependence_t;
19
20typedef struct {
21    uint32_t len;
22    const ffrt_dependence_t* items;
23} ffrt_deps_t;
24```
25
26#### 参数
27
28- `len`:数据依赖个数。
29- `items`:数据依赖数组,数据长度等于`len`。
30- `ptr`:数据地址。
31- `type`:区分数据和`task_handle`。
32
33#### 描述
34
35`ffrt_dependence_t`作用等同C++的`dependence`,`ffrt_deps_t`作用等同C++的`std::vector<dependence>`。
36
37#### 样例
38
39```c
40// 创建数据依赖
41int x = 0;
42ffrt_dependence_t dependence[1];
43dependence[0].type = ffrt_dependence_data;
44dependence[0].ptr = &x;
45ffrt_deps_t deps;
46deps.len = 1;
47deps.items = dependence;
48
49// 创建任务依赖
50ffrt_task_handle_t task = ffrt_submit_h_base(user_function_header, NULL, NULL, &attr);
51ffrt_dependence_t dependence[1];
52dependence[0].type = ffrt_dependence_task;
53dependence[0].ptr = task;
54ffrt_deps_t deps;
55deps.len = 1;
56deps.items = dependence;
57```
58
59### ffrt_task_attr_t
60
61#### 声明
62
63```c
64typedef struct {
65    uint32_t storage[(ffrt_task_attr_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
66} ffrt_task_attr_t;
67```
68
69#### 描述
70
71任务的属性描述,在提交普通任务或者队列任务时,可以通过`ffrt_task_attr_t`来配置其属性。
72
73#### 方法
74
75##### ffrt_task_attr_init
76
77```c
78FFRT_C_API int ffrt_task_attr_init(ffrt_task_attr_t* attr);
79```
80
81参数
82
83- `attr`:`ffrt_task_attr_t`对象指针。
84
85返回值
86
87- 0表示成功,-1表示失败。
88
89描述
90
91- 初始化一个`ffrt_task_attr_t`对象。
92
93##### ffrt_task_attr_destroy
94
95```c
96FFRT_C_API void ffrt_task_attr_destroy(ffrt_task_attr_t* attr);
97```
98
99参数
100
101- `attr`:`ffrt_task_attr_t`对象指针。
102
103描述
104
105- 去初始化一个`ffrt_task_attr_t`对象。
106
107##### ffrt_task_attr_set_name
108
109```c
110FFRT_C_API void ffrt_task_attr_set_name(ffrt_task_attr_t* attr, const char* name);
111```
112
113参数
114
115- `attr`:`ffrt_task_attr_t`对象指针。
116- `name`:任务的名称。
117
118描述
119
120- 设置任务的名称,名称是用于维测信息打印的一种有效信息。
121
122##### ffrt_task_attr_get_name
123
124```c
125FFRT_C_API const char* ffrt_task_attr_get_name(const ffrt_task_attr_t* attr);
126```
127
128参数
129
130- `attr`:`ffrt_task_attr_t`对象指针。
131
132返回值
133
134- 任务的名称。
135
136描述
137
138- 获取设置的任务名称。
139
140##### ffrt_task_attr_set_qos
141
142```c
143FFRT_C_API void ffrt_task_attr_set_qos(ffrt_task_attr_t* attr, ffrt_qos_t qos);
144```
145
146参数
147
148- `attr`:`ffrt_task_attr_t`对象指针。
149- `qos`:QoS等级。
150
151描述
152
153- 设置任务的QoS等级,QoS等级影响任务执行时的系统资源供给。不设置QoS的情况下,队列任务默认继承队列的QoS等级,普通任务默认设置为`ffrt_qos_default`。
154
155##### ffrt_task_attr_get_qos
156
157```c
158FFRT_C_API ffrt_qos_t ffrt_task_attr_get_qos(const ffrt_task_attr_t* attr);
159```
160
161参数
162
163- `attr`:`ffrt_task_attr_t`对象指针。
164
165返回值
166
167- QoS等级。
168
169描述
170
171- 获取设置的QoS等级。
172
173##### ffrt_task_attr_set_delay
174
175```c
176FFRT_C_API void ffrt_task_attr_set_delay(ffrt_task_attr_t* attr, uint64_t delay_us);
177```
178
179参数
180
181- `attr`:`ffrt_task_attr_t`对象指针。
182- `delay_us`:调度时延,单位为微秒。
183
184描述
185
186- 设置任务的调度时延,任务会在时延间隔之后才调度执行。不设置的情况下,默认时延为零。
187
188##### ffrt_task_attr_get_delay
189
190```c
191FFRT_C_API uint64_t ffrt_task_attr_get_delay(const ffrt_task_attr_t* attr);
192```
193
194参数
195
196- `attr`:`ffrt_task_attr_t`对象指针。
197
198返回值
199
200- 调度时延。
201
202描述
203
204- 获取设置的调度时延。
205
206##### ffrt_task_attr_set_queue_priority
207
208```c
209FFRT_C_API void ffrt_task_attr_set_queue_priority(ffrt_task_attr_t* attr, ffrt_queue_priority_t priority);
210```
211
212参数
213
214- `attr`:`ffrt_task_attr_t`对象指针。
215- `priority`:任务优先级。
216
217描述
218
219- 设置任务的优先级,目前仅并发队列任务支持优先级功能,同一个并发队列中按照优先级顺序来调度任务。不设置的情况下,任务默认优先级`ffrt_queue_priority_low`。
220
221##### ffrt_task_attr_get_queue_priority
222
223```c
224FFRT_C_API ffrt_queue_priority_t ffrt_task_attr_get_queue_priority(const ffrt_task_attr_t* attr);
225```
226
227参数
228
229- `attr`:`ffrt_task_attr_t`对象指针。
230
231返回值
232
233- 任务优先级。
234
235描述
236
237- 获取设置的优先级。
238
239##### ffrt_task_attr_set_stack_size
240
241```c
242FFRT_C_API void ffrt_task_attr_set_stack_size(ffrt_task_attr_t* attr, uint64_t size);
243```
244
245参数
246
247- `attr`:`ffrt_task_attr_t`对象指针。
248- `size`:协程栈大小,单位为字节。
249
250描述
251
252- 设置任务的协程栈大小,影响任务执行过程中最大的调用栈使用空间上限。在不设置的情况下,默认的协程栈大小为1MB。
253
254##### ffrt_task_attr_get_stack_size
255
256```c
257FFRT_C_API uint64_t ffrt_task_attr_get_stack_size(const ffrt_task_attr_t* attr);
258```
259
260参数
261
262- `attr`:`ffrt_task_attr_t`对象指针。
263
264返回值
265
266- 协程栈大小。
267
268描述
269
270- 获取设置的协程栈大小。
271
272##### ffrt_task_attr_set_timeout
273
274```c
275FFRT_C_API void ffrt_task_attr_set_timeout(ffrt_task_attr_t* attr, uint64_t timeout_us);
276```
277
278参数
279
280- `attr`:`ffrt_task_attr_t`对象指针。
281- `timeout_us`:任务的调度超时时间,单位为微秒。
282
283描述
284
285- 设置任务的调度超时时间,仅针对队列任务生效,当队列任务超过该时间还未调度执行时,打印告警信息。不设置的情况下,默认没有调度超时限制。
286
287##### ffrt_task_attr_get_timeout
288
289```c
290FFRT_C_API uint64_t ffrt_task_attr_get_timeout(const ffrt_task_attr_t* attr);
291```
292
293参数
294
295- `attr`:`ffrt_task_attr_t`对象指针。
296
297返回值
298
299- 调度超时时间。
300
301描述
302
303- 获取设置的超时时间。
304
305#### 样例
306
307```c
308// 提交一个普通任务,其名称为"sample_task",QoS等级为background,调度时延为1ms,协程栈大小为2MB
309ffrt_task_attr_t attr;
310ffrt_task_attr_init(&attr);
311ffrt_task_attr_set_name(&attr, "sample_task");
312ffrt_task_attr_set_qos(&attr, ffrt_qos_background);
313ffrt_task_attr_set_delay(&attr, 1000);
314ffrt_task_attr_set_stack_size(&attr, 2 * 1024 * 1024);
315ffrt_submit_base(user_function_header, NULL, NULL, &attr);
316ffrt_task_attr_destroy(&attr);
317```
318
319### ffrt_alloc_auto_managed_function_storage_base
320
321#### 声明
322
323```c
324typedef enum {
325    ffrt_function_kind_general,
326    ffrt_function_kind_queue,
327} ffrt_function_kind_t;
328
329typedef void(*ffrt_function_t)(void*);
330typedef struct {
331    ffrt_function_t exec;
332    ffrt_function_t destroy;
333    uint64_t reserve[2];
334} ffrt_function_header_t;
335
336FFRT_C_API void *ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_t kind);
337```
338
339#### 参数
340
341- `kind`:提交普通任务选择`ffrt_function_kind_general`,提交队列任务选择`ffrt_function_kind_queue`。
342- `exec`:任务实际执行调用的函数指针。
343- `destroy`:任务完成后调用的函数指针,可用于资源清理等用途。
344- `reserve`:内部预留空间,用户请勿使用该成员。
345
346#### 返回值
347
348- 返回存储用户任务执行体的指针。
349
350#### 描述
351
352分配了一块内存空间,内存空间头部为`ffrt_function_header_t`结构体(返回指针可转换为`ffrt_function_header_t*`指针使用)。头部后留有64字节的可用空间,用户可自定义使用该空间,通常用于入参或返回值的存储。
353
354#### 样例
355
356- 样例1:生成一个不带参数和返回值的任务执行体:
357
358    ```c
359    void foo(void* data)
360    {
361        printf("foo\n");
362    }
363
364    void after_foo(void* data)
365    {
366        printf("after_foo\n");
367    }
368
369    int main()
370    {
371        ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
372
373        func->exec = foo;
374        func->destroy = after_foo;
375
376        ffrt_submit_base(func, NULL, NULL, NULL);
377        ffrt_wait();
378
379        return 0;
380    }
381    ```
382
383- 样例2:生成一个带参数和返回值的任务执行体:
384
385    ```c
386    int foo(int x, int y)
387    {
388        printf("foo: x = %d, y = %d\n", x, y);
389        return x + y;
390    }
391
392    void after_foo(void* data)
393    {
394        printf("after_foo\n");
395    }
396
397    // 用户自定义任务执行体,可携带参数和返回值
398    struct user_defined_function {
399        ffrt_function_header_t header; // 头部内存为ffrt_function_header_t
400        int arg1; // 参数1
401        int arg2; // 参数2
402        int ret; // 返回值
403    };
404
405    // 将foo包装成void(*)(void*)的exec函数类型
406    void exec_func_wrapper(void* header)
407    {
408        user_defined_function* func = (user_defined_function*)header;
409        func->ret = foo(func->arg1, func->arg2); // 内部展开真正的foo函数,传递参数,获取返回值
410    }
411
412    int main()
413    {
414        user_defined_function* func = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
415
416        func->header.exec = exec_func_wrapper;
417        func->header.destroy = after_foo;
418        func->arg1 = 1;
419        func->arg2 = 2;
420
421        ffrt_submit_base((ffrt_function_header_t*)func, NULL, NULL, NULL);
422        ffrt_wait();
423
424        printf("ret = %d\n", func->ret);
425        return 0;
426    }
427    ```
428
429### ffrt_submit_base
430
431#### 声明
432
433```c
434FFRT_C_API void 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);
435```
436
437#### 参数
438
439- `f`:用户的任务执行体,可以是原生的`ffrt_function_header_t`类型,也可以基于`ffrt_function_header_t`自定义拓展类型。
440- `in_deps`:任务的输入数据依赖。输入数据依赖通常以实际数据的地址表达,也支持`ffrt_task_handle_t`作为一种特殊输入依赖。
441- `out_deps`:任务的输出数据依赖。输出数据依赖通常以实际数据的地址表达,不支持`ffrt_task_handle_t`。
442- `attr`:任务的属性设置。
443
444#### 描述
445
446提交一个普通任务,任务支持相关属性设置,在输入依赖解除后任务可调度执行,任务执行完成后解除输出依赖。
447
448#### 样例
449
450- 样例1:提交带属性的任务:
451
452    ```c
453    void foo(void* data)
454    {
455        printf("foo\n");
456    }
457
458    void after_foo(void* data)
459    {
460        printf("after_foo\n");
461    }
462
463    // 提交一个任务
464    ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
465    func->exec = foo;
466    func->destroy = after_foo;
467    ffrt_submit_base(func, NULL, NULL, NULL);
468
469    // 提交一个带属性的任务
470    ffrt_task_attr_t attr;
471    ffrt_task_attr_init(&attr);
472    ffrt_task_attr_set_name(&attr, "sample_task");
473    ffrt_task_attr_set_qos(&attr, ffrt_qos_background);
474    ffrt_submit_base(func, NULL, NULL, &attr);
475    ```
476
477- 样例2:提交带数据依赖的任务:
478
479    ```c
480    // 提交两个带数据依赖的任务,任务间存在Read-After-Write依赖关系
481    #include "math.h"
482    #include "ffrt.h"
483
484    void cos_func(float* x, float* y)
485    {
486        *y = std::cos(*x);
487    }
488
489    void tan_func(float* y, float* z)
490    {
491        *z = std::tan(*y);
492    }
493
494    struct user_defined_function {
495        ffrt_function_header_t header;
496        float* arg1; // 参数1
497        float* arg2; // 参数2
498    };
499
500    void cos_func_wrapper(void* header)
501    {
502        user_defined_function* func = (user_defined_function*)header;
503        cos_func(func->arg1, func->arg2);
504    }
505
506    void tan_func_wrapper(void* header)
507    {
508        user_defined_function* func = (user_defined_function*)header;
509        tan_func(func->arg1, func->arg2);
510    }
511
512    void destroy(void* header) {}
513
514    int main()
515    {
516        float x = 0.5f, y, z;
517
518        user_defined_function* func1 = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
519        func1->header.exec = cos_func_wrapper;
520        func1->header.destroy = destroy;
521        func1->arg1 = &x;
522        func1->arg2 = &y;
523
524        user_defined_function* func2 = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
525        func2->header.exec = tan_func_wrapper;
526        func2->header.destroy = destroy;
527        func2->arg1 = &y;
528        func2->arg2 = &z;
529
530        ffrt_dependence_t dependence_x[1];
531        dependence_x[0].type = ffrt_dependence_data;
532        dependence_x[0].ptr = &x;
533        ffrt_deps_t deps_x;
534        deps_x.len = 1;
535        deps_x.items = dependence_x;
536        ffrt_dependence_t dependence_y[1];
537        dependence_y[0].type = ffrt_dependence_data;
538        dependence_y[0].ptr = &y;
539        ffrt_deps_t deps_y;
540        deps_y.len = 1;
541        deps_y.items = dependence_y;
542        ffrt_dependence_t dependence_z[1];
543        dependence_z[0].type = ffrt_dependence_data;
544        dependence_z[0].ptr = &z;
545        ffrt_deps_t deps_z;
546        deps_z.len = 1;
547        deps_z.items = dependence_z;
548
549        ffrt_submit_base((ffrt_function_header_t*)func1, &deps_x, &deps_y, NULL);
550        ffrt_submit_base((ffrt_function_header_t*)func2, &deps_y, &deps_z, NULL);
551
552        ffrt_wait();
553        printf("x = %f, y = %f, z = %f\n", x, y, z);
554        return 0;
555    }
556    ```
557
558### ffrt_submit_h_base
559
560#### 声明
561
562```c
563typedef void* ffrt_task_handle_t;
564
565FFRT_C_API ffrt_task_handle_t 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);
566```
567
568#### 参数
569
570- `f`:用户的任务执行体,可以是原生的`ffrt_function_header_t`类型,也可以基于`ffrt_function_header_t`自定义拓展类型。
571- `in_deps`:任务的输入数据依赖。输入数据依赖通常以实际数据的地址表达,也支持`ffrt_task_handle_t`作为一种特殊输入依赖。
572- `out_deps`:任务的输出数据依赖。输出数据依赖通常以实际数据的地址表达,不支持`ffrt_task_handle_t`。
573- `attr`:任务的属性设置。
574
575#### 返回值
576
577- `ffrt_task_handle_t`任务的句柄。
578
579#### 描述
580
581相比于`ffrt_submit_base`接口,增加了任务句柄的返回值。
582
583#### 样例
584
585```c
586// 提交一个任务,获取任务句柄
587ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
588func->exec = foo;
589func->destroy = after_foo;
590ffrt_task_handle_t t = ffrt_submit_h_base(func, NULL, NULL, NULL);
591// 注意C API的ffrt_task_handle_t需要用户调用ffrt_task_handle_destroy显式销毁
592ffrt_task_handle_destroy(t);
593```
594
595### ffrt_task_handle_inc_ref
596
597#### 声明
598
599```c
600FFRT_C_API uint32_t ffrt_task_handle_inc_ref(ffrt_task_handle_t handle);
601```
602
603#### 参数
604
605- `handle`:任务句柄。
606
607#### 返回值
608
609- 任务的引用计数。
610
611#### 描述
612
613通过任务句柄增加对应任务的引用计数,每次调用引用计数加一。用于控制任务的生命周期使用,当引用计数不为零时,对应的任务资源不会被释放。注意`ffrt_submit_h_base`返回的`ffrt_task_handle_t`默认已有一个引用计数。通过`ffrt_task_handle_destroy`销毁`ffrt_task_handle_t`时默认减去一个引用计数。
614
615### ffrt_task_handle_dec_ref
616
617#### 声明
618
619```c
620FFRT_C_API uint32_t ffrt_task_handle_dec_ref(ffrt_task_handle_t handle);
621```
622
623#### 参数
624
625- `handle`:任务句柄。
626
627#### 返回值
628
629- 任务的引用计数。
630
631#### 描述
632
633通过任务句柄减去对应任务的引用计数,每次调用引用计数减一。
634
635### ffrt_task_handle_destroy
636
637#### 声明
638
639```c
640FFRT_C_API void ffrt_task_handle_destroy(ffrt_task_handle_t handle);
641```
642
643#### 参数
644
645- `handle`:任务句柄。
646
647#### 描述
648
649销毁任务句柄,同时默认减去一个任务引用计数。
650
651### ffrt_wait
652
653#### 声明
654
655```c
656FFRT_C_API void ffrt_wait(void);
657```
658
659#### 描述
660
661同步等待所有前序提交的同级任务完成。
662
663#### 样例
664
665```c
666// 同步三个任务完成
667ffrt_submit_base(func1, NULL, NULL, NULL);
668ffrt_submit_base(func2, NULL, NULL, NULL);
669ffrt_submit_base(func3, NULL, NULL, NULL);
670ffrt_wait();
671```
672
673### ffrt_wait_deps
674
675#### 声明
676
677```c
678FFRT_C_API void ffrt_wait_deps(const ffrt_deps_t* deps);
679```
680
681#### 参数
682
683- `deps`:需要同步的数据依赖。
684
685#### 描述
686
687同步对应的数据依赖解除。
688
689#### 样例
690
691```c
692// 构建x的数据依赖
693int x = 0;
694ffrt_dependence_t dependence[1];
695dependence[0].type = ffrt_dependence_data;
696dependence[0].ptr = &x;
697ffrt_deps_t deps;
698deps.len = 1;
699deps.items = dependence;
700
701// 提交一个写任务
702ffrt_submit_base(func, NULL, &deps, NULL);
703
704// 同步写任务解除数据依赖
705ffrt_wait_deps(&deps);
706```
707
708### ffrt_set_worker_stack_size
709
710#### 声明
711
712```c
713FFRT_C_API ffrt_error_t ffrt_set_worker_stack_size(ffrt_qos_t qos, size_t stack_size);
714```
715
716#### 参数
717
718- `qos`:QoS等级。
719- `stack_size`:Worker线程栈大小,单位是字节。
720
721#### 返回值
722
723- 错误码
724
725#### 描述
726
727在开始提交任务前,设置某一组QoS的Worker线程栈大小(Worker线程按QoS分组,组间互不影响,组内线程属性相同)。通常该接口用于用户提交非协程任务且函数栈超过默认上限的场景,不设置时线程栈和OS默认规格一致。
728
729#### 样例
730
731```c
732// 把qos_default的Worker线程组的线程栈大小设置成2MB
733ffrt_error_t ret = ffrt_set_worker_stack_size(ffrt_qos_default, 2 * 1024 * 1024);
734```
735
736### ffrt_this_task_update_qos
737
738#### 声明
739
740```c
741FFRT_C_API int ffrt_this_task_update_qos(ffrt_qos_t qos);
742```
743
744#### 参数
745
746- `qos`:QoS等级。
747
748#### 返回值
749
750- 0表示成功,1表示失败。
751
752#### 描述
753
754在任务执行过程中,动态修改任务的QoS等级。注意该接口在任务的函数闭包内使用,修改的是当前正在执行的任务的QoS等级,接口调用会使任务先挂起一次再恢复执行。
755
756#### 样例
757
758```c
759// 一个qos_background的任务执行过程中动态修改QoS等级
760ffrt::submit([]() {
761    ...
762    int ret = ffrt_this_task_update_qos(ffrt_qos_user_initiated);
763    ...
764}, ffrt::task_attr().qos(ffrt::qos_background));
765```
766
767### ffrt_this_task_get_qos
768
769#### 声明
770
771```c
772FFRT_C_API ffrt_qos_t ffrt_this_task_get_qos(void);
773```
774
775#### 返回值
776
777- QoS等级。
778
779#### 描述
780
781获取当前正在执行任务的QoS等级。
782
783#### 样例
784
785```c
786// 一个任务执行过程中动态获取其QoS等级
787ffrt::submit([]() {
788    ...
789    // 获取的qos等于ffrt_qos_background
790    ffrt_qos_t qos = ffrt_this_task_get_qos();
791    ...
792}, ffrt::task_attr().qos(ffrt::qos_background));
793```
794
795### ffrt_this_task_get_id
796
797#### 声明
798
799```c
800FFRT_C_API uint64_t ffrt_this_task_get_id(void);
801```
802
803#### 返回值
804
805- 任务的id。
806
807#### 描述
808
809获取当前正在执行任务的id。
810
811#### 样例
812
813```c
814// 一个任务执行过程中动态获取其任务id
815ffrt::submit([]() {
816    ...
817    // 获取的唯一任务id
818    uint64_t task_id = ffrt_this_task_get_id();
819    ...
820}, ffrt::task_attr().qos(ffrt::qos_background));
821```
822
823### ffrt_task_handle_get_id
824
825#### 声明
826
827```c
828FFRT_C_API uint64_t ffrt_task_handle_get_id(ffrt_task_handle_t handle);
829```
830
831#### 参数
832
833- `handle`:任务句柄。
834
835#### 返回值
836
837- 任务的id。
838
839#### 描述
840
841获取任务句柄对应的任务id。
842
843#### 样例
844
845```c
846ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general);
847func->exec = foo;
848func->destroy = after_foo;
849ffrt_task_handle_t t = ffrt_submit_h_base(func, NULL, NULL, NULL);
850// 通过句柄获取任务对应的id
851uint64_t task_id = ffrt_task_handle_get_id(t);
852ffrt_task_handle_destroy(t);
853```
854
855## 任务队列
856
857### ffrt_queue_attr_t
858
859#### 声明
860
861```c
862typedef struct {
863    uint32_t storage[(ffrt_queue_attr_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
864} ffrt_queue_attr_t;
865```
866
867#### 描述
868
869用于配置队列的属性,如 QoS、超时时间、回调函数和最大并发数。
870
871#### 方法
872
873##### ffrt_queue_attr_init
874
875```c
876int ffrt_queue_attr_init(ffrt_queue_attr_t* attr)
877```
878
879参数
880
881- `attr`:队列属性指针。
882
883返回值
884
885- 返回0表示成功,其他值表示失败。
886
887描述
888
889- 初始化队列属性对象。
890
891##### ffrt_queue_attr_destroy
892
893```c
894void ffrt_queue_attr_destroy(ffrt_queue_attr_t* attr)
895```
896
897参数
898
899- `attr`:队列属性指针。
900
901描述
902
903- 销毁队列属性对象。
904
905##### ffrt_queue_attr_set_qos
906
907```c
908void ffrt_queue_attr_set_qos(ffrt_queue_attr_t* attr, ffrt_qos_t qos)
909```
910
911参数
912
913- `attr`:队列属性指针。
914- `qos`:QoS等级。
915
916描述
917
918- 设置队列的QoS等级。
919
920##### ffrt_queue_attr_get_qos
921
922```c
923ffrt_qos_t ffrt_queue_attr_get_qos(const ffrt_queue_attr_t* attr)
924```
925
926参数
927
928- `attr`:队列属性指针。
929
930返回值
931
932- 返回当前QoS等级。
933
934描述
935
936- 获取当前属性中设置的QoS等级。
937
938##### ffrt_queue_attr_set_timeout
939
940```c
941void ffrt_queue_attr_set_timeout(ffrt_queue_attr_t* attr, uint64_t timeout_us)
942```
943
944参数
945
946- `attr`:队列属性指针。
947- `timeout_us`:超时时间(微秒)。
948
949描述
950
951- 设置队列的超时时间(以微秒为单位)。
952
953##### ffrt_queue_attr_get_timeout
954
955```c
956uint64_t ffrt_queue_attr_get_timeout(const ffrt_queue_attr_t* attr)
957```
958
959参数
960
961- `attr`:队列属性指针。
962
963返回值
964
965- 返回当前超时阈值(微秒)。
966
967描述
968
969- 获取当前属性中设置的超时时间。
970
971##### ffrt_queue_attr_set_callback
972
973```c
974void ffrt_queue_attr_set_callback(ffrt_queue_attr_t* attr, ffrt_function_header_t* f)
975```
976
977参数
978
979- `attr`:队列属性指针。
980- `f`:是任务执行器的指针,描述了该CPU任务如何执行和销毁。
981
982描述
983
984- 设置检测到队列任务超时后执行的回调函数。
985
986##### ffrt_queue_attr_get_callback
987
988```c
989ffrt_function_header_t* ffrt_queue_attr_get_callback(const ffrt_queue_attr_t* attr)
990```
991
992参数
993
994- `attr`:队列属性指针。
995
996返回值
997
998- 返回任务执行器的指针,描述了该CPU任务如何执行和销毁。
999
1000描述
1001
1002- 获取当前属性中设置的超时回调函数。
1003
1004##### ffrt_queue_attr_set_max_concurrency
1005
1006```c
1007void ffrt_queue_attr_set_max_concurrency(ffrt_queue_attr_t* attr, const int max_concurrency)
1008```
1009
1010参数
1011
1012- `attr`:队列属性指针。
1013- `max_concurrency`:最大并发数。
1014
1015描述
1016
1017- 设置队列的最大并发数(仅支持并发队列)。
1018
1019##### ffrt_queue_attr_get_max_concurrency
1020
1021```c
1022int ffrt_queue_attr_get_max_concurrency(const ffrt_queue_attr_t* attr)
1023```
1024
1025参数
1026
1027- `attr`:队列属性指针。
1028
1029返回值
1030
1031- 返回当前最大并发数。
1032
1033描述
1034
1035- 获取当前属性中设置的最大并发数(仅支持并发队列)。
1036
1037#### 样例
1038
1039```c
1040#include <stdio.h>
1041#include "ffrt.h"
1042
1043using namespace ffrt;
1044using namespace std;
1045
1046int main(int narg, char** argv)
1047{
1048    ffrt_queue_attr_t queue_attr;
1049    // 初始化队列属性,必需
1050    int result = ffrt_queue_attr_init(&queue_attr);
1051
1052    ffrt_queue_attr_set_qos(&queue_attr, static_cast<int>(ffrt_qos_utility));
1053
1054    ffrt_queue_attr_set_timeout(&queue_attr, 10000);
1055
1056    ffrt_queue_attr_set_callback(&queue_attr, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue));
1057
1058    int x = 0;
1059    std::function<void()>&& basicFunc = [&x]() { x += 1; };
1060    ffrt_function_header_t* func = ffrt_queue_attr_get_callback(&queue_attr);
1061
1062    // 销毁队列属性,必需
1063    ffrt_queue_attr_destroy(&queue_attr);
1064}
1065```
1066
1067### ffrt_queue_t
1068
1069#### 声明
1070
1071```c
1072typedef void* ffrt_queue_t;
1073```
1074
1075#### 描述
1076
1077队列指针,提供一系列C接口支持队列任务的提交、取消、等待和排队任务数量查询。
1078
1079#### 方法
1080
1081##### ffrt_queue_create
1082
1083```c
1084ffrt_queue_t ffrt_queue_create(ffrt_queue_type_t type, const char* name, const ffrt_queue_attr_t* attr)
1085```
1086
1087参数
1088
1089- `type`:队列类型(如`ffrt_queue_serial`或`ffrt_queue_concurrent`)。
1090- `name`:队列名称。
1091- `attr`:队列属性。
1092
1093返回值
1094
1095- `ffrt_queue_t`:成功则返回一个非空的队列句柄;否则返回空指针。
1096
1097描述
1098
1099- 创建指定类型和名称的队列。
1100
1101##### ffrt_queue_destroy
1102
1103```c
1104void ffrt_queue_destroy(ffrt_queue_t queue)
1105```
1106
1107参数
1108
1109- `queue`:队列的句柄。
1110
1111描述
1112
1113- 销毁一个队列。
1114
1115##### ffrt_queue_submit
1116
1117```c
1118void ffrt_queue_submit(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)
1119```
1120
1121参数
1122
1123- `queue`:队列的句柄。
1124- `f`:任务执行器的指针,描述了该CPU任务如何执行和销毁。
1125- `attr`:任务属性。
1126
1127描述
1128
1129- 提交任务到队列中。
1130
1131##### ffrt_queue_submit_h
1132
1133```c
1134ffrt_task_handle_t ffrt_queue_submit_h(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr)
1135```
1136
1137参数
1138
1139- `queue`:队列的句柄。
1140- `f`:任务执行器的指针,描述了该CPU任务如何执行和销毁。
1141- `attr`:任务属性。
1142
1143返回值
1144
1145- `ffrt_task_handle_t`:成功则返回一个非空的任务句柄;否则返回空指针。
1146
1147描述
1148
1149- 提交任务到队列中,并返回任务句柄。
1150
1151##### ffrt_queue_submit_head
1152
1153```c
1154void ffrt_queue_submit_head(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr);
1155```
1156
1157参数
1158
1159- `queue`:队列的句柄。
1160- `f`:任务执行器的指针,描述了该CPU任务如何执行和销毁。
1161- `attr`:任务属性。
1162
1163描述
1164
1165- 提交任务到队列头部。
1166
1167##### ffrt_queue_submit_head_h
1168
1169```c
1170ffrt_task_handle_t ffrt_queue_submit_head_h(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr);
1171```
1172
1173参数
1174
1175- `queue`:队列的句柄。
1176- `f`:任务执行器的指针,描述了该CPU任务如何执行和销毁。
1177- `attr`:任务属性。
1178
1179返回值
1180
1181- `ffrt_task_handle_t`:成功则返回一个非空的任务句柄;否则返回空指针。
1182
1183描述
1184
1185- 提交任务到队列头部,并返回任务句柄。
1186
1187##### ffrt_queue_wait
1188
1189```c
1190void ffrt_queue_wait(ffrt_task_handle_t handle)
1191```
1192
1193参数
1194
1195- `ffrt_task_handle_t`:任务句柄。
1196
1197描述
1198
1199- 等待一个队列任务完成。
1200
1201##### ffrt_queue_cancel
1202
1203```c
1204int ffrt_queue_cancel(ffrt_task_handle_t handle)
1205```
1206
1207参数
1208
1209- `ffrt_task_handle_t`:任务句柄。
1210
1211返回值
1212
1213- 返回0表示成功,其他值表示失败。
1214
1215描述
1216
1217- 取消一个队列任务。
1218
1219##### ffrt_get_main_queue
1220
1221```c
1222ffrt_queue_t ffrt_get_main_queue();
1223```
1224
1225返回值
1226
1227- 主线程队列。
1228
1229描述
1230
1231- 获取主线程队列,用于FFRT线程与主线程通信。
1232
1233##### ffrt_get_current_queue
1234
1235```c
1236ffrt_queue_t ffrt_get_current_queue();
1237```
1238
1239返回值
1240
1241- ArkTS Worker线程任务队列。
1242
1243描述
1244
1245- 此接口已于API 15版本后废弃,不建议继续使用。
1246- 获取ArkTS Worker线程队列,用于FFRT线程与ArkTS Worker线程通信。
1247
1248##### ffrt_queue_get_task_cnt
1249
1250```c
1251uint64_t ffrt_queue_get_task_cnt(ffrt_queue_t queue)
1252```
1253
1254参数
1255
1256- `queue`:队列的句柄。
1257
1258返回值
1259
1260- 此队列排队的任务数。
1261
1262描述
1263
1264- 获取在队列中排队等待的任务数量。
1265
1266#### 样例
1267
1268```c
1269#include <stdio.h>
1270#include "ffrt.h"
1271
1272using namespace ffrt;
1273using namespace std;
1274
1275int main()
1276{
1277    ffrt_queue_attr_t queue_attr;
1278    // 1、初始化队列属性,必需
1279    (void)ffrt_queue_attr_init(&queue_attr);
1280
1281    // 2、创建串行队列,并返回队列句柄 queue_handle
1282    ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr);
1283
1284    int result = 0;
1285    std::function<void()>&& basicFunc = [&result]() { result += 1; };
1286
1287    // 3、提交串行任务
1288    ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
1289
1290    // 4、提交串行任务,并返回任务句柄
1291    ffrt_task_handle_t t1 = ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
1292    // 5、等待指定任务执行完成
1293    ffrt_queue_wait(t1);
1294
1295    ffrt_task_handle_t t2 = ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr);
1296    // 6、取消句柄为 t2 的任务
1297    int ret = ffrt_queue_cancel(t2);
1298
1299    // 7、销毁提交给串行队列任务的句柄 t1 和 t2,必需
1300    ffrt_task_handle_destroy(t1);
1301    ffrt_task_handle_destroy(t2);
1302    // 8、销毁队列属性,必需
1303    ffrt_queue_attr_destroy(&queue_attr);
1304    // 9、销毁队列句柄,必需
1305    ffrt_queue_destroy(queue_handle);
1306}
1307```
1308
1309## 同步原语
1310
1311### ffrt_mutexattr_t
1312
1313#### 声明
1314
1315```c
1316typedef enum {
1317    ffrt_error = -1,
1318    ffrt_success = 0,
1319    ffrt_error_nomem = ENOMEM,
1320    ffrt_error_timedout = ETIMEDOUT,
1321    ffrt_error_busy = EBUSY,
1322    ffrt_error_inval = EINVAL
1323} ffrt_error_t;
1324
1325typedef enum {
1326    ffrt_mutex_normal = 0,
1327    ffrt_mutex_recursive = 2,
1328    ffrt_mutex_default = ffrt_mutex_normal
1329} ffrt_mutex_type;
1330
1331struct ffrt_mutexattr_t;
1332
1333int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
1334int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
1335int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
1336int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
1337```
1338
1339#### 描述
1340
1341- FFRT提供的类似pthread mutexattr的性能实现。
1342
1343#### 方法
1344
1345##### ffrt_mutexattr_init
1346
1347```c
1348FFRT_C_API int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
1349```
1350
1351参数
1352
1353- `attr`:FFRT锁属性。
1354
1355返回值
1356
1357- `attr`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1358
1359描述
1360
1361- 初始化`mutexattr`。
1362
1363##### ffrt_mutexattr_destroy
1364
1365```c
1366FFRT_C_API int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
1367```
1368
1369参数
1370
1371- `attr`:FFRT锁属性。
1372
1373返回值
1374
1375- `attr`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1376
1377描述
1378
1379- 销毁mutexattr。
1380
1381##### ffrt_mutexattr_settype
1382
1383```c
1384FFRT_C_API int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
1385```
1386
1387参数
1388
1389- `attr`:FFRT锁属性。
1390- `type`:FFRT锁类型,当前仅支持互斥锁`ffrt_mutex_normal`和递归锁`ffrt_mutex_recursive`。
1391
1392返回值
1393
1394- `attr`不为空且`type`有效返回`ffrt_success`,否则返回`ffrt_error_inval`。
1395
1396描述
1397
1398- 设置FFRT锁属性。
1399
1400##### ffrt_mutexattr_gettype
1401
1402```c
1403FFRT_C_API int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
1404```
1405
1406参数
1407
1408- `attr`:FFRT锁属性。
1409- `type`:FFRT锁类型指针。
1410
1411返回值
1412
1413- `attr`和`type`均不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1414
1415描述
1416
1417- 获取FFRT锁属性。
1418
1419#### 样例
1420
1421```c
1422#include "ffrt.h"
1423
1424void ffrt_c_mutexattr_test()
1425{
1426    ffrt_mutexattr_t attr;
1427    ffrt_mutex_t recursive_mtx;
1428    EXPECT_EQ(ffrt_mutexattr_init(nullptr), ffrt_error_inval);
1429    EXPECT_EQ(ffrt_mutexattr_settype(nullptr, -1), ffrt_error_inval);
1430    EXPECT_EQ(ffrt_mutexattr_gettype(nullptr, nullptr), ffrt_error_inval);
1431    EXPECT_EQ(ffrt_mutexattr_destroy(nullptr), ffrt_error_inval);
1432}
1433```
1434
1435### ffrt_mutex_t
1436
1437- FFRT 提供的类似pthread mutex的性能实现,但不支持类似`PTHREAD_MUTEX_INITIALIZER`的初始化。
1438
1439#### 声明
1440
1441```c
1442typedef enum {
1443    ffrt_error = -1,
1444    ffrt_success = 0,
1445    ffrt_error_nomem = ENOMEM,
1446    ffrt_error_timedout = ETIMEDOUT,
1447    ffrt_error_busy = EBUSY,
1448    ffrt_error_inval = EINVAL
1449} ffrt_error_t;
1450
1451struct ffrt_mutex_t;
1452
1453struct ffrt_mutexattr_t;
1454
1455int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr);
1456int ffrt_mutex_lock(ffrt_mutex_t* mutex);
1457int ffrt_mutex_unlock(ffrt_mutex_t* mutex);
1458int ffrt_mutex_trylock(ffrt_mutex_t* mutex);
1459int ffrt_mutex_destroy(ffrt_mutex_t* mutex);
1460```
1461
1462#### 描述
1463
1464- 该接口支持在FFRT任务内部调用,也支持在FFRT任务外部调用。
1465- 该接口能够避免pthread传统的`pthread_mutex_t`在抢不到锁时陷入内核态的问题,在使用得当的条件下将会有更好的性能。
1466- C API 中的`ffrt_mutexattr_t`需要用户调用`ffrt_mutexattr_init`和`ffrt_mutexattr_destroy`显示创建和销毁,否则其行为是未定义的。
1467- C API 中的`ffrt_mutex_t`需要用户调用`ffrt_mutex_init`和`ffrt_mutex_destroy`显式创建和销毁,否则其行为是未定义的。
1468- C API 中的`ffrt_mutex_t`对象的置空和销毁由用户完成,对同一个`ffrt_mutex_t`仅能调用一次`ffrt_mutex_destroy`,重复对同一个 ffrt_mutex_t 调用`ffrt_mutex_destroy`,其行为是未定义的。
1469- C API 中的同一个`ffrt_mutexattr_t`只能调用一次`ffrt_mutexattr_init`和`ffrt_mutexattr_destroy`,重复调用其行为是未定义的。
1470- 用户需要在调用`ffrt_mutex_init`之后和调用`ffrt_mutex_destroy`之前显示调用`ffrt_mutexattr_destroy`。
1471- 在`ffrt_mutex_destroy`之后再对`ffrt_mutex_t`进行访问,其行为是未定义的。
1472
1473#### 方法
1474
1475##### ffrt_mutex_init
1476
1477```c
1478FFRT_C_API int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr);
1479```
1480
1481参数
1482
1483- `mutex`:指向所操作的锁指针。
1484- `attr`:FFRT锁属性,attr的有效值范围是:空指针或等于`ffrt_mutex_normal`代表互斥锁,`ffrt_mutex_recursive`代表递归锁。
1485
1486返回值
1487
1488- 如果`mutex`不为空且`attr`在有效值范围内返回`ffrt_success`,否则返回`ffrt_error_inval`。
1489
1490描述
1491
1492- 初始化FFRT锁。
1493
1494##### ffrt_mutex_destroy
1495
1496```c
1497FFRT_C_API int ffrt_mutex_destroy(ffrt_mutex_t* mutex);
1498```
1499
1500参数
1501
1502- `mutex`:指向所操作的锁指针。
1503
1504返回值
1505
1506- `mutex`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1507
1508描述
1509
1510- 对指定的互斥锁/递归锁进行销毁操作。
1511
1512##### ffrt_mutex_lock
1513
1514```c
1515FFRT_C_API int ffrt_mutex_lock(ffrt_mutex_t* mutex);
1516```
1517
1518参数
1519
1520- `mutex`:指向所操作的锁指针。
1521
1522返回值
1523
1524- `mutex`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1525
1526描述
1527
1528- 对指定的互斥锁/递归锁进行加锁操作,该方法会阻塞当前任务直到能成功获得锁。
1529
1530##### ffrt_mutex_unlock
1531
1532```c
1533FFRT_C_API int ffrt_mutex_unlock(ffrt_mutex_t* mutex);
1534```
1535
1536参数
1537
1538- `mutex`:指向所操作的锁指针。
1539
1540返回值
1541
1542- `mutex`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1543
1544描述
1545
1546- 对指定的互斥锁/递归锁进行解锁操作。
1547
1548##### ffrt_mutex_trylock
1549
1550```c
1551FFRT_C_API int ffrt_mutex_trylock(ffrt_mutex_t* mutex);
1552```
1553
1554参数
1555
1556- `mutex`:指向所操作的锁指针。
1557
1558返回值
1559
1560- `mutex`为空返回ffrt_error_inval,`mutex`不为空且持锁成功返回`ffrt_success`,`mutex`不为空且持锁失败返回`ffrt_error_busy`。
1561
1562描述
1563
1564- 对指定的互斥锁/递归锁进行尝试加锁操作。
1565
1566#### 样例
1567
1568```c
1569#include "ffrt.h"
1570
1571void ffrt_c_mutex_test()
1572{
1573    ffrt_mutexattr_t attr;
1574    ffrt_mutex_t lock;
1575    int ret = 0;
1576    int sum = 0;
1577    int type = ffrt_mutex_default;
1578    ret = ffrt_mutexattr_init(&attr);
1579    EXPECT_EQ(ret, ffrt_success);
1580    ret = ffrt_mutexattr_settype(&attr, ffrt_mutex_recursive);
1581    EXPECT_EQ(ret, ffrt_success);
1582    ret = ffrt_mutexattr_gettype(&attr, &type);
1583    EXPECT_EQ(ret, ffrt_success);
1584    ret = ffrt_mutex_init(&lock, &attr);
1585    EXPECT_EQ(type, ffrt_mutex_recursive);
1586    ffrt::submit([&]() {
1587        ffrt_mutex_lock(&lock);
1588        EXPECT_EQ(ffrt_mutex_trylock(&lock), ffrt_success);
1589        sum++;
1590        ffrt_mutex_lock(&lock);
1591        EXPECT_EQ(ffrt_mutex_trylock(&lock), ffrt_success);
1592        sum++;
1593        ffrt_mutex_unlock(&lock);
1594        ffrt_mutex_unlock(&lock);
1595        ffrt_mutex_unlock(&lock);
1596        ffrt_mutex_unlock(&lock);
1597        }, {}, {});
1598
1599    ffrt::wait();
1600
1601    ffrt_mutexattr_destroy(&attr);
1602    ffrt_mutex_destroy(&lock);
1603}
1604```
1605
1606### ffrt_cond_t
1607
1608- FFRT提供的类似pthread信号量的性能实现,但不支持类似`PTHREAD_COND_INITIALIZER`的初始化。
1609
1610#### 声明
1611
1612```c
1613typedef enum {
1614    ffrt_error = -1,
1615    ffrt_success = 0,
1616    ffrt_error_nomem = ENOMEM,
1617    ffrt_error_timedout = ETIMEDOUT,
1618    ffrt_error_busy = EBUSY,
1619    ffrt_error_inval = EINVAL
1620} ffrt_error_t;
1621
1622typedef struct {
1623    uint32_t storage[(ffrt_cond_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
1624} ffrt_cond_t;
1625
1626int ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr);
1627int ffrt_cond_signal(ffrt_cond_t* cond);
1628int ffrt_cond_broadcast(ffrt_cond_t* cond);
1629int ffrt_cond_wait(ffrt_cond_t*cond, ffrt_mutex_t* mutex);
1630int ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point);
1631int ffrt_cond_destroy(ffrt_cond_t* cond);
1632```
1633
1634#### 描述
1635
1636- 该接口支持在FFRT任务内部调用,也支持在FFRT任务外部调用。
1637- 该功能能够避免传统的`pthread_cond_t`在条件不满足时陷入内核的问题,在使用得当的条件下将会有更好的性能。
1638- 注意:C API 中的`ffrt_cond_t`需要用户调用`ffrt_cond_init`和`ffrt_cond_destroy`显式创建和销毁,而C++ API 中依赖构造和析构自动完成。
1639- 注意:C API 中的`ffrt_cond_t`对象的置空和销毁由用户完成,对同一个`ffrt_cond_t`仅能调用一次`ffrt_cond_destroy`,重复对同一个`ffrt_cond_t`调用`ffrt_cond_destroy`,其行为是未定义的。
1640- 注意:在`ffrt_cond_destroy`之后再对`ffrt_cond_t`进行访问,其行为是未定义的。
1641
1642#### 方法
1643
1644##### ffrt_cond_init
1645
1646```c
1647FFRT_C_API int ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr);
1648```
1649
1650参数
1651
1652- `cond`:指向所操作的信号量的指针。
1653- `attr`:属性设定,空指针表示使用默认属性。
1654
1655返回值
1656
1657- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1658
1659描述
1660
1661- 初始化FFRT条件变量。
1662
1663##### ffrt_cond_destroy
1664
1665```c
1666FFRT_C_API int ffrt_cond_destroy(ffrt_cond_t* cond);
1667```
1668
1669参数
1670
1671- `cond`:指向所操作的信号量的指针。
1672
1673返回值
1674
1675- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1676
1677描述
1678
1679- 销毁FFRT条件变量。
1680
1681##### ffrt_cond_signal
1682
1683```c
1684FFRT_C_API int ffrt_cond_signal(ffrt_cond_t* cond);
1685```
1686
1687参数
1688
1689- `cond`:指向所操作的信号量的指针。
1690
1691返回值
1692
1693- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1694
1695描述
1696
1697- 该方法用于唤醒一个等待条件变量的任务。
1698
1699##### ffrt_cond_broadcast
1700
1701```c
1702FFRT_C_API int ffrt_cond_broadcast(ffrt_cond_t* cond);
1703```
1704
1705参数
1706
1707- `cond`:指向所操作的信号量的指针。
1708
1709返回值
1710
1711- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1712
1713描述
1714
1715- 该方法用于唤醒所有等待条件变量的任务。
1716
1717##### ffrt_cond_wait
1718
1719```c
1720FFRT_C_API int ffrt_cond_wait(ffrt_cond_t* cond, ffrt_mutex_t* mutex);
1721```
1722
1723参数
1724
1725- `cond`:指向所操作的信号量的指针。
1726- `mutex`:指向要在阻塞期间解锁的互斥锁的指针。
1727
1728返回值
1729
1730- `cond`和`mutex`均不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1731
1732描述
1733
1734- 方法用于在条件变量上等待。任务在调用该方法时会释放传入的互斥量,并进入等待状态,直到另一个任务通知条件变量,才会重新获取互斥量并继续执行。
1735- 此方法通常与`ffrt_mutex_lock`或`ffrt_mutex_trylock`一起使用,确保在进入等待状态之前已经持有互斥量。
1736
1737##### ffrt_cond_timedwait
1738
1739```c
1740FFRT_C_API int ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point);
1741```
1742
1743参数
1744
1745- `cond`:指向所操作的信号量的指针。
1746- `mutex`:指向要在阻塞期间解锁的互斥锁的指针。
1747- `time_point`:指向指定等待时限时间的对象的指针。
1748
1749返回值
1750
1751- `cond`和`mutex`和`time_point`均不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。
1752
1753描述
1754
1755- 该方法用于在条件变量上等待,直到指定的超时时间到达。
1756- 与`ffrt_cond_wait`不同,`ffrt_cond_timedwait`方法允许任务在条件变量上等待一段时间,如果在指定时间内没有收到通知,任务将被唤醒该函数返回。
1757
1758#### 样例
1759
1760```c
1761#include "ffrt.h"
1762
1763void ffrt_c_cond_test()
1764{
1765    int a = 0;
1766    ffrt_cond_t cond;
1767    ffrt_mutex_t lock_;
1768    ffrt_cond_init(&cond, nullptr);
1769    ffrt_mutex_init(&lock_, nullptr);
1770
1771    for (int i = 0; i < 3; i++) {
1772        ffrt::submit([&]() {
1773            int timeout = 2000;
1774            struct timespec tm = timeoutms_to_tm(timeout);
1775            ffrt_mutex_lock(&lock_);
1776            auto start = std::chrono::high_resolution_clock::now();
1777            int ret = ffrt_cond_timedwait(&cond, &lock_, &tm);
1778            auto end = std::chrono::high_resolution_clock::now();
1779            a = 123;
1780            ffrt_mutex_unlock(&lock_);
1781            std::chrono::duration<double, std::milli> elapsed = end-start;
1782            double t = elapsed.count();
1783            std::cout << "ffrt_cond_timedwait " << t << " ms\n";
1784            EXPECT_EQ(ret, ffrt_success);
1785            }, {}, {});
1786    }
1787
1788    ffrt::submit([&]() {
1789        ffrt_usleep(1000 * 1000);
1790        ffrt_mutex_lock(&lock_);
1791        a = 5;
1792        ffrt_cond_broadcast(&cond);
1793        ffrt_mutex_unlock(&lock_);
1794        }, {}, {});
1795    ffrt::wait();
1796    ffrt_cond_destroy(&cond);
1797    ffrt_mutex_destroy(&lock_);
1798    EXPECT_EQ(a, 123);
1799}
1800```
1801
1802## 阻塞原语
1803
1804### ffrt_usleep
1805
1806#### 声明
1807
1808```c
1809FFRT_C_API int ffrt_usleep(uint64_t usec);
1810```
1811
1812#### 参数
1813
1814- `usec`:睡眠的微秒数。
1815
1816#### 描述
1817
1818- FFRT提供的类似C11 sleep和Linux usleep的性能实现。
1819- 该接口只能在FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。
1820- 该接口睡眠精度为微秒。
1821- 该功能能够避免传统的`sleep`睡眠时陷入内核的问题,在使用得当的条件下将会有更好的性能。
1822
1823#### 样例
1824
1825```c
1826#include "ffrt.h"
1827
1828void ffrt_c_usleep_test()
1829{
1830    ffrt::submit([=]() { ffrt_usleep(10); }, {}, {});
1831    ffrt::wait();
1832}
1833```
1834
1835## 协同原语
1836
1837### ffrt_yield
1838
1839#### 声明
1840
1841```c
1842FFRT_C_API void ffrt_yield();
1843```
1844
1845#### 描述
1846
1847- 当前任务主动让出CPU执行资源,允许其他可执行的任务运行,如果没有其他可执行的任务,`yield`无效。
1848- 该接口只能在 FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。
1849- 此函数的确切行为取决于实现,特别是使用中的FFRT调度程序的机制和系统状态。
1850
1851#### 样例
1852
1853```c
1854#include "ffrt.h"
1855
1856void ffrt_c_yield_test()
1857{
1858    int count = 12;
1859    for (int i = 0; i < count; i++) {
1860        ffrt::submit(
1861            [&]() {
1862            ffrt_usleep(100);
1863            printf("test");
1864            ffrt_yield();
1865        },
1866            {}, {});
1867    }
1868    ffrt::wait();
1869}
1870```
1871
1872## 定时器
1873
1874### ffrt_timer_t
1875
1876#### 声明
1877
1878```c
1879typedef int ffrt_timer_t;
1880typedef void (*ffrt_timer_cb)(void* data);
1881```
1882
1883#### 描述
1884
1885提供定时器相关的功能。
1886
1887#### 方法
1888
1889##### ffrt_timer_start
1890
1891声明
1892
1893```c
1894FFRT_C_API ffrt_timer_t ffrt_timer_start(ffrt_qos_t qos, uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat);
1895```
1896
1897参数
1898
1899- `qos`:QoS等级。
1900- `timeout`:定时器时间,单位是毫秒。
1901- `cb`:到期后的回调函数。
1902- `data`:回调函数的输入参数。
1903- `repeat`:是否循环定时器。
1904
1905返回值
1906
1907- `ffrt_timer_t`定时器句柄。
1908
1909描述
1910
1911- 启动一个定时器,定时器到期且未被取消的话,执行回调函数。如果设置`repeat`为`true`,定时器到期后会重复设置。
1912
1913##### ffrt_timer_stop
1914
1915声明
1916
1917```c
1918FFRT_C_API int ffrt_timer_stop(ffrt_qos_t qos, ffrt_timer_t handle);
1919```
1920
1921参数
1922
1923- `qos`:QoS等级。
1924- `handle`:定时器句柄。
1925
1926返回值
1927
1928- 0表示成功,-1表示失败。
1929
1930描述
1931
1932- 取消一个定时器,和`ffrt_timer_start`配对使用。
1933
1934#### 样例
1935
1936- 样例1:使用单次定时器:
1937
1938    ```c
1939    #include <stdint.h>
1940    #include <unistd.h>
1941    #include "ffrt.h"
1942
1943    static void test_fun(void *data)
1944    {
1945        *(int *)data += 1;
1946    }
1947
1948    void (*cb)(void *) = test_fun;
1949
1950    int main(int narg, char** argv)
1951    {
1952        static int x = 0;
1953        void *data = &x;
1954        uint64_t timeout = 200;
1955        // 启动定时器,在200ms后执行回调函数
1956        int handle = ffrt_timer_start(ffrt_qos_default, timeout, data, cb, false);
1957        usleep(300000);
1958        // 定时器已经执行,取消无效
1959        ffrt_timer_stop(ffrt_qos_default, handle);
1960        printf("data: %d\n", x); // x值变成1
1961        return 0;
1962    }
1963    ```
1964
1965- 样例2:使用循环定时器:
1966
1967    ```c
1968    #include <stdint.h>
1969    #include <unistd.h>
1970    #include "ffrt.h"
1971
1972    static void test_fun(void *data)
1973    {
1974        *(int *)data += 1;
1975    }
1976
1977    void (*cb)(void *) = test_fun;
1978
1979    int main(int narg, char** argv)
1980    {
1981        static int x = 0;
1982        void *data = &x;
1983        uint64_t timeout = 200;
1984        // 启动循环定时器,每间隔200ms执行回调函数
1985        int handle = ffrt_timer_start(ffrt_qos_default, timeout, data, cb, true);
1986        usleep(500000);
1987        // 取消循环定时器
1988        ffrt_timer_stop(ffrt_qos_default, handle);
1989        printf("data: %d\n", x); // x的值变成2
1990        return 0;
1991    }
1992    ```
1993
1994## 循环
1995
1996### ffrt_loop_t
1997
1998#### 声明
1999
2000```c
2001typedef void* ffrt_loop_t;
2002```
2003
2004#### 描述
2005
2006提供循环相关的功能。
2007
2008#### 方法
2009
2010##### ffrt_loop_create
2011
2012声明
2013
2014```c
2015FFRT_C_API ffrt_loop_t ffrt_loop_create(ffrt_queue_t queue);
2016```
2017
2018参数
2019
2020- `queue`:loop需要绑定一个FFRT并发队列使用。
2021
2022返回值
2023
2024- `ffrt_loop_t`对象。
2025
2026描述
2027
2028- 创建一个loop,需要绑定一个并发队列存储任务,用户可以向队列中提交任务使其在loop中执行。
2029
2030##### ffrt_loop_destroy
2031
2032声明
2033
2034```c
2035FFRT_C_API int ffrt_loop_destroy(ffrt_loop_t loop);
2036```
2037
2038参数
2039
2040- `loop`:loop对象。
2041
2042返回值
2043
2044- 0表示成功,-1表示失败。
2045
2046描述
2047
2048- 销毁一个loop,同时和队列解除绑定。
2049
2050##### ffrt_loop_run
2051
2052声明
2053
2054```c
2055FFRT_C_API int ffrt_loop_run(ffrt_loop_t loop);
2056```
2057
2058参数
2059
2060- `loop`:loop对象。
2061
2062返回值
2063
2064- 0表示成功,-1表示失败。
2065
2066描述
2067
2068- 启动一个loop,调用此方法的线程会同步执行loop,在loop中会执行队列的任务、监听poller事件触发、监听timer定时器触发。
2069
2070##### ffrt_loop_stop
2071
2072声明
2073
2074```c
2075FFRT_C_API void ffrt_loop_stop(ffrt_loop_t loop);
2076```
2077
2078参数
2079
2080- `loop`:loop对象。
2081
2082描述
2083
2084- 停止一个loop,调用此方法使执行loop的线程退出循环。
2085
2086##### ffrt_loop_epoll_ctl
2087
2088声明
2089
2090```c
2091int ffrt_loop_epoll_ctl(ffrt_loop_t loop, int op, int fd, uint32_t events, void *data, ffrt_poller_cb cb)
2092```
2093
2094参数
2095
2096- `loop`:loop对象。
2097- `op`:fd操作符,参考epoll_ctl的操作类型。
2098- `fd`:事件描述符。
2099- `events`:事件,参考epoll_ctl的事件类型。
2100- `data`:回调函数的入参。
2101- `cb`:回调函数。
2102
2103返回值
2104
2105- 0表示成功,-1表示失败。
2106
2107描述
2108
2109- 管理loop上的监听fd事件,事件的监听和回调执行在loop线程上处理。
2110
2111##### ffrt_loop_timer_start
2112
2113声明
2114
2115```c
2116FFRT_C_API ffrt_timer_t ffrt_loop_timer_start(ffrt_loop_t loop, uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat);
2117```
2118
2119参数
2120
2121- `loop`:loop对象。
2122- `timeout`:定时器时间,单位是毫秒。
2123- `cb`:到期后的回调函数。
2124- `data`:回调函数的输入参数。
2125- `repeat`:是否循环定时器。
2126
2127返回值
2128
2129- `ffrt_timer_t`定时器句柄。
2130
2131描述
2132
2133- 在loop上启动一个定时器,用法和`ffrt_timer_start`一致,只是定时器的监听和回调执行在loop线程上处理。
2134
2135##### ffrt_loop_timer_stop
2136
2137声明
2138
2139```c
2140FFRT_C_API int ffrt_loop_timer_stop(ffrt_loop_t loop, ffrt_timer_t handle);
2141```
2142
2143参数
2144
2145- `loop`:loop对象。
2146- `handle`:定时器句柄。
2147
2148返回值
2149
2150- 0表示成功,-1表示失败。
2151
2152描述
2153
2154- 取消一个定时器,用法和`ffrt_timer_stop`一致。
2155
2156#### 样例
2157
2158- 样例1:循环与并发队列:
2159
2160    ```c
2161    #include <pthread.h>
2162    #include <unistd.h>
2163    #include <stdio.h>
2164    #include "c/loop.h"
2165
2166    void* ThreadFunc(void* p)
2167    {
2168        int ret = ffrt_loop_run(p);
2169        if (ret == 0) {
2170            printf("loop normal operation.");
2171        }
2172        return nullptr;
2173    }
2174
2175    int main(int narg, char** argv)
2176    {
2177        // 创建并发队列
2178        ffrt_queue_attr_t queue_attr;
2179        (void)ffrt_queue_attr_init(&queue_attr);
2180        ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
2181
2182        // 创建loop
2183        auto loop = ffrt_loop_create(queue_handle);
2184
2185        // 启动独立线程来执行loop
2186        pthread_t thread;
2187        pthread_create(&thread, 0, ThreadFunc, loop);
2188
2189        // 终止并销毁loop
2190        ffrt_loop_stop(loop);
2191        int ret = ffrt_loop_destroy(loop);
2192
2193        // 销毁并发队列
2194        ffrt_queue_attr_destroy(&queue_attr);
2195        ffrt_queue_destroy(queue_handle);
2196        return 0;
2197    }
2198    ```
2199
2200- 样例2:循环、并发队列和定时器:
2201
2202    ```c
2203    #include <pthread.h>
2204    #include <unistd.h>
2205    #include <stdio.h>
2206    #include <functional>
2207    #include <sys/epoll.h>
2208    #include <sys/eventfd.h>
2209    #include "c/loop.h"
2210    #include "ffrt.h"
2211
2212    void* ThreadFunc(void* p)
2213    {
2214        int ret = ffrt_loop_run(p);
2215        return nullptr;
2216    }
2217
2218    static void test_fun(void* data)
2219    {
2220        *(int*)data += 1;
2221    }
2222
2223    static void (*cb)(void*) = test_fun;
2224
2225    void testCallBack(void *data, unsigned int events) {}
2226
2227    struct TestData {
2228        int fd;
2229        uint64_t expected;
2230    };
2231
2232    int main(int narg, char** argv)
2233    {
2234        // 创建并发队列
2235        ffrt_queue_attr_t queue_attr;
2236        (void)ffrt_queue_attr_init(&queue_attr);
2237        ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr);
2238
2239        // 创建loop
2240        auto loop = ffrt_loop_create(queue_handle);
2241        int result1 = 0;
2242
2243        // 向loop队列提交一个任务
2244        std::function<void()> &&basicFunc1 = [&result1]() {result1 += 10;};
2245        ffrt_task_handle_t task1 = ffrt_queue_submit_h(queue_handle, ffrt::create_function_wrapper(basicFunc1, ffrt_function_kind_queue), nullptr);
2246
2247        // 启动独立线程来执行loop
2248        pthread_t thread;
2249        pthread_create(&thread, 0, ThreadFunc, loop);
2250
2251        static int x = 0;
2252        int* xf = &x;
2253        void* data = xf;
2254        uint64_t timeout1 = 20;
2255        uint64_t timeout2 = 10;
2256        uint64_t expected = 0xabacadae;
2257
2258        int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
2259        struct TestData testData {.fd = testFd, .expected = expected};
2260
2261        // 向loop注册一个定时器
2262        ffrt_timer_t timeHandle = ffrt_loop_timer_start(loop, timeout1, data, cb, false);
2263
2264        // 向loop注册一个fd监听
2265        int ret = ffrt_loop_epoll_ctl(loop, EPOLL_CTL_ADD, testFd, EPOLLIN, (void*)(&testData), testCallBack);
2266        if (ret == 0) {
2267            printf("ffrt_loop_epoll_ctl执行成功。\n");
2268        }
2269        ssize_t n = write(testFd, &expected, sizeof(uint64_t));
2270        usleep(25000);
2271        // 删除fd监听
2272        ffrt_loop_epoll_ctl(loop, EPOLL_CTL_DEL, testFd, 0, nullptr, nullptr);
2273
2274        // 终止loop
2275        ffrt_loop_stop(loop);
2276        pthread_join(thread, nullptr);
2277
2278        // 删除定时器
2279        ffrt_loop_timer_stop(loop, timeHandle);
2280
2281        // 销毁loop
2282        ret = ffrt_loop_destroy(loop);
2283
2284        // 销毁并发队列
2285        ffrt_queue_attr_destroy(&queue_attr);
2286        ffrt_queue_destroy(queue_handle);
2287        return 0;
2288    }
2289    ```
2290