• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Function Flow Runtime C++ API
2
3## 任务管理
4
5### task_attr
6
7#### 声明
8
9```cpp
10class task_attr;
11```
12
13#### 描述
14
15任务的属性描述,在提交普通任务或者队列任务时,可以通过`task_attr`来配置其属性。
16
17#### 方法
18
19##### set task name
20
21```cpp
22inline task_attr& task_attr::name(const char* name)
23```
24
25参数
26
27- `name`:用户指定的任务名称。
28
29返回值
30
31- `task_attr`对象的引用。
32
33描述
34
35- 设置任务的名称,名称是用于维测信息打印的一种有效信息。
36
37##### get task name
38
39```cpp
40inline const char* task_attr::name() const
41```
42
43返回值
44
45- 任务的名称。
46
47描述
48
49- 获取设置的任务名称。
50
51##### set task qos
52
53```cpp
54inline task_attr& task_attr::qos(qos qos_)
55```
56
57参数
58
59- `qos_`:QoS等级。
60
61返回值
62
63- `task_attr`对象的引用。
64
65描述
66
67- 设置任务的QoS等级,QoS等级影响任务执行时的系统资源供给。不设置QoS的情况下,队列任务默认继承队列的QoS等级,普通任务默认设置为`qos_default`。
68
69##### get task qos
70
71```cpp
72inline int task_attr::qos() const
73```
74
75返回值
76
77- QoS等级。
78
79描述
80
81- 获取设置的QoS等级。
82
83##### set task delay
84
85```cpp
86inline task_attr& task_attr::delay(uint64_t delay_us)
87```
88
89参数
90
91- `delay_us`:调度时延,单位为微秒。
92
93返回值
94
95- `task_attr`对象的引用。
96
97描述
98
99- 设置任务的调度时延,任务会在时延间隔之后才调度执行。不设置的情况下,默认时延为零。
100
101##### get task delay
102
103```cpp
104inline uint64_t task_attr::delay() const
105```
106
107返回值
108
109- 调度时延。
110
111描述
112
113- 获取设置的调度时延。
114
115##### set task priority
116
117```cpp
118inline task_attr& task_attr::priority(ffrt_queue_priority_t prio)
119```
120
121参数
122
123- `prio`:任务优先级。
124
125返回值
126
127- `task_attr`对象的引用。
128
129描述
130
131- 设置任务的优先级,目前仅并发队列任务支持优先级功能,同一个并发队列中按照优先级顺序来调度任务。不设置的情况下,任务默认优先级为`ffrt_queue_priority_low`。
132
133##### get task priority
134
135```cpp
136inline ffrt_queue_priority_t task_attr::priority() const
137```
138
139返回值
140
141- 任务优先级。
142
143描述
144
145- 获取设置的优先级。
146
147##### set task stack_size
148
149```cpp
150inline task_attr& task_attr::stack_size(uint64_t size)
151```
152
153参数
154
155- `size`:协程栈大小,单位为字节。
156
157返回值
158
159- `task_attr`对象的引用。
160
161描述
162
163- 设置任务的协程栈大小,影响任务执行过程中最大的调用栈使用空间上限。在不设置的情况下,默认的协程栈大小为1MB。
164
165##### get task stack_size
166
167```cpp
168inline uint64_t task_attr::stack_size() const
169```
170
171返回值
172
173- 协程栈大小。
174
175描述
176
177- 获取设置的协程栈大小。
178
179##### set task timeout
180
181```cpp
182inline task_attr& task_attr::timeout(uint64_t timeout_us)
183```
184
185参数
186
187- `timeout_us`:任务的调度超时时间,单位为微秒。
188
189返回值
190
191- `task_attr`对象的引用。
192
193描述
194
195- 设置任务的调度超时时间,仅针对队列任务生效,当队列任务超过该时间还未调度执行时,打印告警信息。不设置的情况下,默认没有调度超时限制。
196
197##### get task timeout
198
199```cpp
200inline uint64_t task_attr::timeout() const
201```
202
203返回值
204
205- 调度超时时间。
206
207描述
208
209- 获取设置的超时时间。
210
211#### 样例
212
213```cpp
214// 提交一个普通任务,其名称为"sample_task",QoS等级为background,调度时延为1ms,协程栈大小为2MB
215ffrt::submit([]() { std::cout << "hello world!" << std::endl; }, ffrt::task_attr().name("sample_task").qos(ffrt::qos_background).delay(1000).stack_size(2 * 1024 * 1024));
216
217// 提交一个并发队列任务,其优先级为high,调度超时时间为100ms
218ffrt::queue sample_queue(queue_concurrent, "sample_queue");
219sample_queue.submit([]() { std::cout << "hello world!" << std::endl; }, ffrt::task_attr().priority(ffrt::ffrt_queue_priority_high).timeout(100 * 1000));
220```
221
222### task_handle
223
224#### 声明
225
226```cpp
227class task_handle;
228```
229
230#### 描述
231
232任务的句柄,其作用包括:
233
234- 任务生命周期管理,句柄绑定的任务,在句柄存在的生命周期内,都是有效的。
235- 配合入参为`task_handle`的方法使用,例如任务同步、任务取消、任务查询等。
236
237#### 方法
238
239##### get_id
240
241```cpp
242inline uint64_t task_handle::get_id() const
243```
244
245返回值
246
247- 任务的id标识。
248
249描述
250
251- 获取`task_handle`对应任务的id。
252
253#### 样例
254
255```cpp
256// 通过任务句柄同步一个普通任务完成
257ffrt::task_handle t = ffrt::submit_h([]() { std::cout << "hello world!" << std::endl; });
258ffrt::wait({t});
259
260// 通过任务句柄同步一个队列任务完成
261ffrt::queue* testQueue = new ffrt::queue("test_queue");
262task_handle t = testQueue->submit_h([]() { std::cout << "hello world!" << std::endl; });
263testQueue->wait(t);
264
265// 通过任务句柄取消一个队列任务
266ffrt::queue* testQueue = new ffrt::queue("test_queue");
267task_handle t = testQueue->submit_h([]() { std::cout << "hello world!" << std::endl; });
268int ret = testQueue->cancel(t);
269```
270
271### create_function_wrapper
272
273#### 声明
274
275```cpp
276template<class T>
277inline ffrt_function_header_t* create_function_wrapper(T&& func, ffrt_function_kind_t kind = ffrt_function_kind_general);
278```
279
280#### 参数
281
282- `func`:任务执行的函数闭包。
283- `kind`:提交普通任务选择`ffrt_function_kind_general`,提交队列任务选择`ffrt_function_kind_queue`。
284
285#### 返回值
286
287- 返回任务执行器的指针,描述了该CPU任务如何执行和销毁。
288
289#### 描述
290
291构建FFRT任务的封装函数,此代码为公共代码与具体业务场景无关,`submit`和`queue::submit`函数都已封装此函数,使用FFRT C++ API时无需关心此接口。
292
293#### 样例
294
295具体样例参见[开发步骤](ffrt-development-guideline.md#开发步骤)。
296
297### submit
298
299#### 声明
300
301```cpp
302static inline void submit(std::function<void()>&& func, const task_attr& attr = {});
303static inline void submit(std::function<void()>&& func, std::initializer_list<dependence> in_deps, const task_attr& attr = {});
304static inline void submit(std::function<void()>&& func, std::initializer_list<dependence> in_deps, std::initializer_list<dependence> out_deps, const task_attr& attr = {});
305static inline void submit(std::function<void()>&& func, const std::vector<dependence>& in_deps, const task_attr& attr = {});
306static inline void submit(std::function<void()>&& func, const std::vector<dependence>& in_deps, const std::vector<dependence>& out_deps, const task_attr& attr = {});
307static inline void submit(const std::function<void()>& func, const task_attr& attr = {});
308static inline void submit(const std::function<void()>& func, std::initializer_list<dependence> in_deps, const task_attr& attr = {});
309static inline void submit(const std::function<void()>& func, std::initializer_list<dependence> in_deps, std::initializer_list<dependence> out_deps, const task_attr& attr = {});
310static inline void submit(const std::function<void()>& func, const std::vector<dependence>& in_deps, const task_attr& attr = {});
311static inline void submit(const std::function<void()>& func, const std::vector<dependence>& in_deps, const std::vector<dependence>& out_deps, const task_attr& attr = {});
312```
313
314#### 参数
315
316- `func`:任务执行的函数闭包。
317- `in_deps`:任务的输入数据依赖。支持初始化列表和`vector`形式。输入数据依赖通常以实际数据的地址表达,也支持`task_handle`作为一种特殊输入依赖。
318- `out_deps`:任务的输出数据依赖。支持初始化列表和`vector`形式。输出数据依赖通常以实际数据的地址表达,不支持`task_handle`。
319- `attr`:任务的属性设置。
320
321#### 描述
322
323提交一个普通任务,任务支持相关属性设置,在输入依赖解除后任务可调度执行,任务执行完成后解除输出依赖。
324
325#### 样例
326
327```cpp
328// 提交一个任务
329ffrt::submit([]() { std::cout << "hello world!" << std::endl; });
330
331// 提交一个带属性的任务
332ffrt::submit([]() { std::cout << "hello world!" << std::endl; }, ffrt::task_attr().name("sample_task").qos(ffrt::qos_background));
333
334// 提交两个任务,任务间存在Read-Aftter-Write依赖关系
335float x = 0.5f, y, z;
336ffrt::submit([&]() { y = std::cos(x); }, {&x}, {&y}); // 第一个任务输入依赖x,输出依赖y
337ffrt::submit([&]() { z = std::tan(y); }, {&y}, {&z}); // 第二个任务输入依赖y(和第一个任务产生Read-Aftter-Write依赖),输出依赖z
338
339// 提交两个任务,任务间存在Write-Aftter-Write依赖关系
340float x = 0.5f, y;
341ffrt::submit([&]() { y = std::cos(x); }, {&x}, {&y}); // 第一个任务输入依赖x,输出依赖y
342ffrt::submit([&]() { y = std::tan(y); }, {}, {&y}); // 第二个任务输出依赖y(和第一个任务产生Write-After-Write依赖),注意这里y虽然也是输入依赖,但写法上可以省略
343ffrt::wait({&y});
344
345// 提交两个任务,任务间存在Write-Aftter-Read依赖关系
346float x = 0.5f;
347ffrt::submit([&]() { std::cout << x << std::endl; }, {&x}, {}); // 第一个任务输入依赖x
348ffrt::submit([&]() { x = 1.0f; }, {}, {&x}); // 第二个任务输出依赖x(和第一个任务产生Write-After-Read依赖)
349
350// 提交两个任务,不存在实际依赖,完全可并发
351float x = 0.5f;
352ffrt::submit([&]() { std::cout << x << std::endl; }, {&x}, {}); // 第一个任务输入依赖x
353ffrt::submit([&]() { std::cout << x * 2 << std::endl; }, {&x}, {}); // 第二个任务输入依赖x(和第一个任务不产生依赖关系)
354
355// 使用vector数组存储依赖作为入参
356std::vector<dependence> indeps;
357indeps.emplace_back(&x);
358std::vector<dependence> outdeps;
359outdeps.emplace_back(&y);
360outdeps.emplace_back(&z);
361ffrt::submit([&]() { y = std::cos(x); z = std::tan(x); }, indeps, outdeps);
362```
363
364### submit_h
365
366#### 声明
367
368```cpp
369static inline task_handle submit_h(std::function<void()>&& func, const task_attr& attr = {});
370static inline task_handle submit_h(std::function<void()>&& func, std::initializer_list<dependence> in_deps, const task_attr& attr = {});
371static inline task_handle submit_h(std::function<void()>&& func, std::initializer_list<dependence> in_deps, std::initializer_list<dependence> out_deps, const task_attr& attr = {});
372static inline task_handle submit_h(std::function<void()>&& func, const std::vector<dependence>& in_deps, const task_attr& attr = {});
373static inline task_handle submit_h(std::function<void()>&& func, const std::vector<dependence>& in_deps, const std::vector<dependence>& out_deps, const task_attr& attr = {});
374static inline task_handle submit_h(const std::function<void()>& func, const task_attr& attr = {});
375static inline task_handle submit_h(const std::function<void()>& func, std::initializer_list<dependence> in_deps, const task_attr& attr = {});
376static inline task_handle submit_h(const std::function<void()>& func, std::initializer_list<dependence> in_deps, std::initializer_list<dependence> out_deps, const task_attr& attr = {});
377static inline task_handle submit_h(const std::function<void()>& func, const std::vector<dependence>& in_deps, const task_attr& attr = {});
378static inline task_handle submit_h(const std::function<void()>& func, const std::vector<dependence>& in_deps, const std::vector<dependence>& out_deps, const task_attr& attr = {});
379```
380
381#### 参数
382
383- `func`:任务执行的函数闭包。
384- `in_deps`:任务的输入数据依赖。支持初始化列表和`vector`形式。输入数据依赖通常以实际数据的地址表达,也支持`task_handle`作为一种特殊输入依赖。
385- `out_deps`:任务的输出数据依赖。支持初始化列表和`vector`形式。输出数据依赖通常以实际数据的地址表达,不支持`task_handle`。
386- `attr`:任务的属性设置。
387
388#### 返回值
389
390- 任务的句柄`task_handle`。
391
392#### 描述
393
394相比于`submit`接口,增加了任务句柄的返回值。
395
396#### 样例
397
398```cpp
399// 提交一个普通任务,并通过句柄同步其完成
400ffrt::task_handle t = ffrt::submit_h([]() { std::cout << "hello world!" << std::endl; });
401ffrt::wait({t});
402
403// 通过任务句柄来建立依赖关系
404int x = 0, y, z;
405ffrt::task_handle t1 = ffrt::submit_h([&]() { y = x + 2; }, {&x}, {&y});
406ffrt::task_handle t2 = ffrt::submit_h([&]() { z = x + 4; }, {&x}, {&z});
407ffrt::submit([&]() { z += y; }, {t1, t2}); // 第三个任务,使用前两个任务的句柄作为输入依赖,建立和前两个任务的依赖关系
408```
409
410### wait
411
412#### 声明
413
414```cpp
415static inline void wait();
416static inline void wait(std::initializer_list<dependence> deps);
417static inline void wait(const std::vector<dependence>& deps);
418```
419
420#### 参数
421
422- `deps`:需要同步的数据依赖,支持初始化列表或`vector`形式。
423
424#### 描述
425
426`wait`函数分为多种重载形式:
427
4281. 不带参数的`wait`函数,表示同步等待所有前序提交的同级任务完成。
4292. 带`deps`参数的`wait`函数,表示同步对应的任务依赖解除。
430
431#### 样例
432
433```cpp
434// wait同步一个任务完成
435ffrt::submit([]() { std::cout << "hello world!" << std::endl; });
436ffrt::wait();
437
438// wait同步多个任务完成
439ffrt::submit([]() { std::cout << "this is task1" << std::endl; });
440ffrt::submit([]() { std::cout << "this is task2" << std::endl; });
441ffrt::submit([]() { std::cout << "this is task3" << std::endl; });
442ffrt::wait();
443
444// wait同步一个数据依赖解除
445int x;
446ffrt::submit([&]() { x = 1; }, {}, {&x});
447ffrt::wait({&x});
448
449// wait同步多个数据依赖解除
450int x, y, z;
451ffrt::submit([&]() { x = 1; }, {}, {&x});
452ffrt::submit([&]() { y = 1; }, {}, {&y});
453ffrt::submit([&]() { z = 1; }, {}, {&z});
454ffrt::wait({&x, &y, &z});
455
456// 在嵌套场景下的wait同步任务
457ffrt::submit([]() { std::cout << "this is task1" << std::endl; });
458ffrt::submit([]() {
459    ffrt::submit([]() { std::cout << "this is task2.1" << std::endl; });
460    ffrt::submit([]() { std::cout << "this is task2.2" << std::endl; });
461    ffrt::submit([]() { std::cout << "this is task2.3" << std::endl; });
462    ffrt::wait(); // 同步三个同级子任务完成(2.1、2.2、2.3),不会同步上一级的任务(task1)
463});
464
465// 在嵌套场景下的wait同步数据依赖
466ffrt::submit([&]() { x = 1; std::cout << "this is task1" << std::endl; }, {}, {&x});
467ffrt::submit([]() {
468    ffrt::submit([]() { std::cout << "this is task2.1" << std::endl; });
469    ffrt::submit([]() { std::cout << "this is task2.2" << std::endl; });
470    ffrt::submit([]() { std::cout << "this is task2.3" << std::endl; });
471    ffrt::wait({&x}); // wait同步数据依赖支持跨层级使用,可以同步上一级任务的输出依赖解除(task1)
472});
473```
474
475### set_worker_stack_size
476
477#### 声明
478
479```cpp
480static inline ffrt_error_t set_worker_stack_size(qos qos_, size_t stack_size);
481```
482
483#### 参数
484
485- `qos_`:QoS等级。
486- `stack_size`:Worker线程栈大小,单位是字节。
487
488#### 返回值
489
490- 错误码,可参考`ffrt_error_t`枚举。
491
492#### 描述
493
494在开始提交任务前,设置某一组QoS的Worker线程栈大小(Worker线程按QoS分组,组间互不影响,组内线程属性相同)。通常该接口用于用户提交非协程任务且函数栈超过默认上限的场景,不设置时线程栈和OS默认规格一致。
495
496#### 样例
497
498```cpp
499// 把qos_default的Worker线程组的线程栈大小设置成2MB
500ffrt_error_t ret = set_worker_stack_size(qos_default, 2 * 1024 * 1024);
501```
502
503### update_qos
504
505#### 声明
506
507```cpp
508static inline int this_task::update_qos(qos qos_);
509```
510
511#### 参数
512
513- `qos_`:QoS等级。
514
515#### 返回值
516
517- 0表示成功,1表示失败。
518
519#### 描述
520
521在任务执行过程中,动态修改任务的QoS等级。注意该接口在任务的函数闭包内使用,修改的是当前正在执行的任务的QoS等级,接口调用会使任务先挂起一次再恢复执行。
522
523#### 样例
524
525```cpp
526// 一个qos_background的任务执行过程中动态修改QoS等级
527ffrt::submit([]() {
528    // ...
529    int ret = ffrt::this_task::update_qos(ffrt::qos_user_initiated);
530    // ...
531}, ffrt::task_attr().qos(ffrt::qos_background));
532```
533
534### get_id
535
536#### 声明
537
538```cpp
539static inline uint64_t this_task::get_id();
540```
541
542#### 返回值
543
544- 当前任务的id。
545
546#### 描述
547
548获取当前执行任务的id,注意该接口在任务的函数闭包内使用。
549
550#### 样例
551
552```cpp
553ffrt::submit([&] {
554    uint64_t id = ffrt::this_task::get_id();
555});
556```
557
558## 任务队列
559
560### queue_attr
561
562#### 声明
563
564```cpp
565class queue_attr;
566```
567
568#### 描述
569
570用于配置队列的属性,如QoS、超时时间、回调函数和最大并发数。
571
572#### 方法
573
574##### set queue qos
575
576```cpp
577queue_attr& queue_attr::qos(qos qos_)
578```
579
580参数
581
582- `qos_`:用户指定的QoS等级。
583
584返回值
585
586- 返回当前对象以支持链式调用。
587
588描述
589
590- 设置队列的QoS等级。
591
592##### get queue qos
593
594```cpp
595int queue_attr::qos() const
596```
597
598返回值
599
600- 返回当前QoS等级。
601
602描述
603
604- 获取当前属性中设置的QoS等级。
605
606##### set queue timeout
607
608```cpp
609queue_attr& queue_attr::timeout(uint64_t timeout_us)
610```
611
612参数
613
614- `timeout_us`:队列任务执行超时阈值(微秒)。
615
616返回值
617
618- 返回当前对象以支持链式调用。
619
620描述
621
622- 设置队列的超时时间(以微秒为单位)。
623
624##### get queue timeout
625
626```cpp
627uint64_t queue_attr::timeout() const
628```
629
630返回值
631
632- 返回当前超时阈值(微秒)。
633
634描述
635
636- 获取当前属性中设置的超时时间。
637
638##### set queue callback
639
640```cpp
641queue_attr& queue_attr::callback(const std::function<void()>& func)
642```
643
644参数
645
646- `func`:回调函数。
647
648返回值
649
650- 返回当前对象以支持链式调用。
651
652描述
653
654- 设置检测到队列任务超时后执行的回调函数。
655
656##### get queue callback
657
658```cpp
659ffrt_function_header_t* queue_attr::callback() const
660```
661
662返回值
663
664- 返回任务执行器的指针,描述了该CPU任务如何执行和销毁。
665
666描述
667
668- 获取当前属性中设置的超时回调函数。
669
670##### set queue max_concurrency
671
672```cpp
673queue_attr& queue_attr::max_concurrency(const int max_concurrency)
674```
675
676参数
677
678- `max_concurrency`:最大并发数。
679
680返回值
681
682- 返回当前对象以支持链式调用。
683
684描述
685
686- 设置队列的最大并发数(仅支持并发队列)。
687
688##### get queue max_concurrency
689
690```cpp
691int queue_attr::max_concurrency() const
692```
693
694返回值
695
696- 返回当前最大并发数。
697
698描述
699
700- 获取当前属性中设置的最大并发数(仅支持并发队列)。
701
702#### 样例
703
704```cpp
705#include <stdio.h>
706#include "ffrt.h"
707
708int main()
709{
710    int x = 0;
711    std::function<void()> callbackFunc = [&x]() {
712        x++;
713    };
714
715    // 创建队列,可设置队列优先级,默认为 default 等级
716    ffrt::queue que1("test_1", queue_attr().qos(qos_utility));
717    // 创建队列,可通过设置 timeout 打开队列任务超时监测(默认关闭)
718    // 超时会打印 Error 日志并执行用户设置的 callback(可选)
719    ffrt::queue que2("test_2", ffrt::queue_attr().timeout(1000).callback(callbackFunc));
720    return 0;
721}
722```
723
724### queue
725
726#### 声明
727
728```cpp
729class queue;
730```
731
732#### 描述
733
734用于创建和管理队列,支持队列任务的提交、取消、等待和排队任务数量查询。
735
736#### 方法
737
738##### 队列创建
739
740```cpp
741queue(const char* name, const queue_attr& attr = {})
742queue(const queue_type type, const char* name, const queue_attr& attr = {})
743```
744
745参数
746
747- `type`:队列类型(如`queue_serial`或`queue_concurrent`),省略此入参时默认是`queue_serial`。
748- `name`:队列名称。
749- `attr`:队列属性(可选)。
750
751描述
752
753- 构造函数,创建指定类型和名称的队列。
754
755##### submit
756
757```cpp
758void queue::submit(const std::function<void()>& func, const task_attr& attr = {})
759void queue::submit(std::function<void()>&& func, const task_attr& attr = {})
760```
761
762参数
763
764- `func`:任务函数闭包,支持左值引用和右值引用两个版本。
765- `attr`:任务属性(可选)。
766
767描述
768
769- 提交一个任务到队列中。
770
771##### submit_h
772
773```cpp
774task_handle queue::submit_h(const std::function<void()>& func, const task_attr& attr = {})
775task_handle queue::submit_h(std::function<void()>&& func, const task_attr& attr = {})
776```
777
778参数
779
780- `func`:任务函数闭包,支持左值引用和右值引用两个版本。
781- `attr`:任务属性(可选)。
782
783返回值
784
785- `task_handle`:返回任务句柄。
786
787描述
788
789- 提交一个任务到队列中,并返回任务句柄。
790
791##### submit_head
792
793```cpp
794inline void queue::submit_head(const std::function<void()>& func, const task_attr& attr = {});
795inline void queue::submit_head(std::function<void()>&& func, const task_attr& attr = {});
796```
797
798参数
799
800- `func`:任务函数闭包,支持左值引用和右值引用两个版本。
801- `attr`:任务属性(可选)。
802
803描述
804
805- 提交一个任务到队列头部。
806
807##### submit_head_h
808
809```cpp
810inline task_handle queue::submit_head_h(const std::function<void()>& func, const task_attr& attr = {});
811inline task_handle queue::submit_head_h(std::function<void()>&& func, const task_attr& attr = {});
812```
813
814参数
815
816- `func`:任务函数闭包,支持左值引用和右值引用两个版本。
817- `attr`:任务属性(可选)。
818
819返回值
820
821- `task_handle`:返回任务句柄。
822
823描述
824
825- 提交一个任务到队列头部,并返回任务句柄。
826
827##### cancel
828
829```cpp
830int queue::cancel(const task_handle& handle)
831```
832
833参数
834
835- `handle`:任务句柄。
836
837返回值
838
839- 返回0表示成功,其他值表示失败。
840
841描述
842
843- 取消一个任务。
844
845##### wait
846
847```cpp
848inline void queue::wait(const task_handle& handle)
849```
850
851参数
852
853- `handle`:任务句柄。
854
855描述
856
857- 等待一个任务。
858
859##### get_task_cnt
860
861```cpp
862uint64_t queue::get_task_cnt()
863```
864
865返回值
866
867- 此队列排队的任务数。
868
869描述
870
871- 获取在队列中排队等待的任务数量。
872
873##### get_main_queue
874
875```cpp
876static inline queue* queue::get_main_queue()
877```
878
879返回值
880
881- 主线程队列。
882
883描述
884
885- 获取主线程队列,用于FFRT线程与主线程通信。
886
887#### 样例
888
889```cpp
890#include "ffrt.h"
891
892int main()
893{
894    // 创建队列,可设置队列优先级,默认为 default 等级
895    ffrt::queue que("test_queue", ffrt::queue_attr().qos(ffrt::qos_utility));
896    int x = 0;
897    // 提交串行任务
898    que.submit([&x] { x += 10; });
899    // 提交串行任务,并返回任务句柄
900    ffrt::task_handle t1 = que.submit_h([&x] { x += 10; });
901    // 提交串行任务,设置延时时间 1000us,并返回任务句柄
902    ffrt::task_handle t2 = que.submit_h([&x] { x += 10; }, ffrt::task_attr().delay(1000));
903    // 等待指定任务执行完成
904    que.wait(t1);
905    // 取消句柄为 t2 的任务
906    que.cancel(t2);
907
908    return 0;
909}
910```
911
912## 同步原语
913
914### mutex
915
916#### 声明
917
918```cpp
919class mutex;
920```
921
922#### 描述
923
924- FFRT提供的类似`std::mutex`的性能实现。
925- 该功能能够避免传统的`std::mutex`在抢不到锁时陷入内核的问题,在使用得当的条件下将会有更好的性能。
926
927#### 方法
928
929##### try_lock
930
931```cpp
932inline bool mutex::try_lock();
933```
934
935返回值
936
937- 获取锁是否成功。
938
939描述
940
941- 尝试获取FFRT互斥锁。
942
943##### lock
944
945```cpp
946inline void mutex::lock();
947```
948
949描述
950
951- 获取FFRT互斥锁。
952
953##### unlock
954
955```cpp
956inline void mutex::unlock();
957```
958
959描述
960
961- 释放FFRT互斥锁。
962
963#### 样例
964
965```cpp
966#include "ffrt.h"
967
968void ffrt_mutex_test()
969{
970    int x = 0;
971    int y = 0;
972    int i = 1;
973    ffrt::mutex lock;
974    auto thread1Func = [&]() {
975        ffrt::submit([&]() {
976            ffrt::this_task::sleep_for(10);
977            while (true) {
978                if (lock.try_lock()) {
979                    EXPECT_EQ(x, 1);
980                    lock.unlock();
981                    return;
982                } else {
983                    y++;
984                    EXPECT_EQ(y, (i++));
985                    ffrt::this_task::sleep_for(10);
986                }
987            }
988            }, {}, {}, ffrt::task_attr().name("t2"));
989        ffrt::wait();
990    };
991
992    auto thread2Func = [&]() {
993        ffrt::submit([&]() {
994            lock.lock();
995            ffrt::this_task::sleep_for(50);
996            x++;
997            lock.unlock();
998            }, {}, {}, ffrt::task_attr().name("t1"));
999        ffrt::wait();
1000    };
1001
1002    std::thread t1(thread1Func);
1003    std::thread t2(thread2Func);
1004    t1.join();
1005    t2.join();
1006}
1007```
1008
1009### recursive_mutex
1010
1011#### 声明
1012
1013```cpp
1014class recursive_mutex;
1015```
1016
1017#### 描述
1018
1019- FFRT提供的类似`std::recursive_mutex`的性能实现。
1020- 该功能能够避免传统的`std::recursive_mutex`在抢不到锁时陷入内核的问题,在使用得当的条件下将会有更好的性能。
1021
1022#### 方法
1023
1024##### try_lock
1025
1026```cpp
1027inline bool recursive_mutex::try_lock();
1028```
1029
1030返回值
1031
1032- 获取锁是否成功。
1033
1034描述
1035
1036- 尝试获取FFRT递归锁。
1037
1038##### lock
1039
1040```cpp
1041inline void recursive_mutex::lock();
1042```
1043
1044描述
1045
1046- 获取FFRT递归锁。
1047
1048##### unlock
1049
1050```cpp
1051inline bool recursive_mutex::unlock();
1052```
1053
1054描述
1055
1056- 释放FFRT递归锁。
1057
1058#### 样例
1059
1060```cpp
1061#include "ffrt.h"
1062void ffrt_recursive_mutex_test()
1063{
1064    ffrt::recursive_mutex lock;
1065    int sum = 0;
1066    ffrt::submit([&]() {
1067        lock.lock();
1068        EXPECT_EQ(lock.try_lock(), true);
1069        sum++;
1070        lock.lock();
1071        EXPECT_EQ(lock.try_lock(), true);
1072        sum++;
1073        lock.unlock();
1074        lock.unlock();
1075        lock.unlock();
1076        lock.unlock();
1077        }, {}, {});
1078    ffrt::wait();
1079}
1080```
1081
1082### condition_variable
1083
1084#### 声明
1085
1086```cpp
1087enum class cv_status { no_timeout, timeout };
1088
1089class condition_variable;
1090```
1091
1092#### 描述
1093
1094- FFRT 提供的类似`std::condition_variable`的性能实现。
1095- 该接口只能在FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。
1096- 该功能能够避免传统的`std::condition_variable`在条件不满足时陷入内核的问题,在使用得当的条件下将会有更好的性能。
1097
1098#### 方法
1099
1100##### wait_until
1101
1102```cpp
1103template <typename Clock, typename Duration, typename Pred>
1104bool condition_variable::wait_until(std::unique_lock<mutex>& lk, const std::chrono::time_point<Clock, Duration>& tp, Pred&& pred) noexcept;
1105```
1106
1107参数
1108
1109- `lk`:mutex互斥量。
1110- `tp`:等待时间。
1111- `pred`:检查是否等待函数。
1112
1113返回值
1114
1115- 是否满足判断条件。
1116
1117描述
1118
1119- 该方法用于在指定时间点之前,阻塞当前任务并等待一个条件变量的通知,直到满足给定的谓词(Predicate)或者超时。
1120
1121##### wait_for
1122
1123```cpp
1124template <typename Rep, typename Period, typename Pred>
1125bool condition_variable::wait_for(std::unique_lock<mutex>& lk, const std::chrono::duration<Rep, Period>& sleepTime, Pred&& pred)
1126```
1127
1128参数
1129
1130- `lk`:mutex互斥量。
1131- `sleepTime`:等待时间。
1132- `pred`:检查是否等待函数。
1133
1134返回值
1135
1136- 是否满足判断条件。
1137
1138描述
1139
1140- 该方法用于在指定时间点之前,阻塞当前任务并等待一个条件变量的通知,直到满足给定的谓词(Predicate)或者超时。
1141
1142##### wait
1143
1144```cpp
1145template <typename Pred>
1146void condition_variable::wait(std::unique_lock<mutex>& lk, Pred&& pred);
1147```
1148
1149参数
1150
1151- `lk`:mutex互斥量。
1152- `pred`:检查是否等待函数。
1153
1154描述
1155
1156- 该方法用于等待某个条件变量的通知,直到满足给定的谓词(Predicate)。
1157
1158##### notify_one
1159
1160```cpp
1161void condition_variable::notify_one() noexcept;
1162```
1163
1164描述
1165
1166- 该方法用于通知一个正在等待该条件变量的线程,唤醒它继续执行。具体哪个线程被唤醒,由操作系统的调度器决定。
1167
1168##### notify_all
1169
1170```cpp
1171void condition_variable::notify_all() noexcept;
1172```
1173
1174描述
1175
1176- 该方法用于通知所有正在等待该条件变量的线程,唤醒它继续执行。这些线程会争夺获取锁并继续执行。
1177
1178#### 样例
1179
1180```cpp
1181#include "ffrt.h"
1182
1183void ffrt_condition_variable_test()
1184{
1185    const int sleepTime = 50 * 1000;
1186    const int checkDelayTime = 10 * 1000;
1187    const std::chrono::milliseconds waitTime = 100ms;
1188    ffrt::condition_variable cond;
1189    ffrt::mutex lock_;
1190    int val = 0;
1191    int predVal = 0;
1192    const int lastVal = 2;
1193
1194    auto threadWaitFunc = [&]() {
1195        std::unique_lock lck(lock_);
1196        bool ret = cond.wait_until(lck, std::chrono::steady_clock::now() + waitTime, [&] { return predVal == 1; });
1197        EXPECT_EQ(val, 1);
1198        EXPECT_EQ(predVal, 1);
1199        val = lastVal;
1200        EXPECT_EQ(ret, true);
1201    };
1202
1203    auto threadNotifyFunc = [&]() {
1204        val = 1;
1205        usleep(sleepTime);
1206        predVal = 1;
1207        cond.notify_one();
1208    };
1209
1210    std::thread tWait(threadWaitFunc);
1211    std::thread tNotify(threadNotifyFunc);
1212    tWait.join();
1213    tNotify.join();
1214    usleep(checkDelayTime);
1215    EXPECT_EQ(val, lastVal);
1216}
1217```
1218
1219## 阻塞原语
1220
1221### sleep
1222
1223#### 描述
1224
1225- FFRT提供的类似`std::this_thread::sleep_for`和`std::this_thread::sleep_until`的性能实现。
1226- 该接口只能在FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。
1227- 该功能能够避免传统的`std::this_thread::sleep_for`睡眠时陷入内核的问题,在使用得当的条件下将会有更好的性能。
1228- 该接口调用后实际睡眠时长不小于配置值。
1229
1230#### 方法
1231
1232##### sleep_for
1233
1234```cpp
1235template <class _Rep, class _Period>
1236inline void this_task::sleep_for(const std::chrono::duration<_Rep, _Period>& d);
1237```
1238
1239参数
1240
1241- `d`:要休眠的持续时间。
1242
1243描述
1244
1245- 该方法用于让当前任务休眠指定的持续时间。
1246
1247##### sleep_until
1248
1249```cpp
1250template<class _Clock, class _Duration>
1251inline void this_task::sleep_until(
1252    const std::chrono::time_point<_Clock, _Duration>& abs_time);
1253```
1254
1255参数
1256
1257- `abs_time`:绝对时间点,表示任务应该被唤醒的目标时间。
1258
1259描述
1260
1261- 该方法用于让当前任务休眠直到指定的绝对时间点。
1262
1263#### 样例
1264
1265```cpp
1266#include <chrono>
1267#include "ffrt.h"
1268
1269void ffrt_sleep_test()
1270{
1271    ffrt::submit([] {
1272        ffrt::this_task::sleep_for(2000);
1273    });
1274    ffrt::wait();
1275}
1276```
1277
1278## 协同原语
1279
1280### yield
1281
1282#### 声明
1283
1284```cpp
1285static inline void this_task::yield();
1286```
1287
1288#### 描述
1289
1290- 当前任务主动让出CPU执行资源,让其他可以被执行的任务先执行,如果没有其他可被执行的任务,`yield`无效。
1291- 该接口只能在FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。
1292- 此函数的确切行为取决于实现,特别是使用中的FFRT调度程序的机制和系统状态。
1293
1294#### 样例
1295
1296```cpp
1297#include <chrono>
1298#include "ffrt.h"
1299
1300void ffrt_yield_test()
1301{
1302    const std::chrono::milliseconds setTime = 5ms;
1303    ffrt::submit([&]() {
1304        ffrt::this_task::yield();
1305        ffrt::this_task::sleep_for(setTime);
1306        ffrt::submit([&]() {
1307            ffrt::this_task::sleep_for(setTime);
1308            ffrt::this_task::yield();
1309            }, {}, {});
1310        ffrt::wait();
1311        }, {}, {});
1312
1313    ffrt::submit([&]() {
1314        ffrt::this_task::sleep_for(setTime);
1315        ffrt::this_task::yield();
1316        }, {}, {});
1317
1318    ffrt::wait();
1319}
1320```
1321