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