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