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