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