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 22task_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 40const char* task_attr::name() const; 41``` 42 43返回值 44 45- 任务的名称。 46 47描述 48 49- 获取设置的任务名称。 50 51##### set task qos 52 53```cpp 54task_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 72int task_attr::qos() const; 73``` 74 75返回值 76 77- QoS等级。 78 79描述 80 81- 获取设置的QoS等级。 82 83##### set task delay 84 85```cpp 86task_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 104uint64_t task_attr::delay() const; 105``` 106 107返回值 108 109- 调度时延。 110 111描述 112 113- 获取设置的调度时延。 114 115##### set task priority 116 117```cpp 118task_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 136ffrt_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 150task_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 168uint64_t task_attr::stack_size() const; 169``` 170 171返回值 172 173- 协程栈大小。 174 175描述 176 177- 获取设置的协程栈大小。 178 179##### set task timeout 180 181```cpp 182task_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 200uint64_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 242uint64_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> 277ffrt_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 void submit(std::function<void()>&& func, const task_attr& attr = {}); 303static void submit(std::function<void()>&& func, std::initializer_list<dependence> in_deps, const task_attr& attr = {}); 304static void submit(std::function<void()>&& func, std::initializer_list<dependence> in_deps, std::initializer_list<dependence> out_deps, const task_attr& attr = {}); 305static void submit(std::function<void()>&& func, const std::vector<dependence>& in_deps, const task_attr& attr = {}); 306static void submit(std::function<void()>&& func, const std::vector<dependence>& in_deps, const std::vector<dependence>& out_deps, const task_attr& attr = {}); 307static void submit(const std::function<void()>& func, const task_attr& attr = {}); 308static void submit(const std::function<void()>& func, std::initializer_list<dependence> in_deps, const task_attr& attr = {}); 309static void submit(const std::function<void()>& func, std::initializer_list<dependence> in_deps, std::initializer_list<dependence> out_deps, const task_attr& attr = {}); 310static void submit(const std::function<void()>& func, const std::vector<dependence>& in_deps, const task_attr& attr = {}); 311static 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 task_handle submit_h(std::function<void()>&& func, const task_attr& attr = {}); 370static task_handle submit_h(std::function<void()>&& func, std::initializer_list<dependence> in_deps, const task_attr& attr = {}); 371static 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 task_handle submit_h(std::function<void()>&& func, const std::vector<dependence>& in_deps, const task_attr& attr = {}); 373static 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 task_handle submit_h(const std::function<void()>& func, const task_attr& attr = {}); 375static task_handle submit_h(const std::function<void()>& func, std::initializer_list<dependence> in_deps, const task_attr& attr = {}); 376static 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 task_handle submit_h(const std::function<void()>& func, const std::vector<dependence>& in_deps, const task_attr& attr = {}); 378static 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 void wait(); 416static void wait(std::initializer_list<dependence> deps); 417static 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 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 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 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- 不建议在`func`中调用`exit`函数,可能导致未定义行为。 656 657##### get queue callback 658 659```cpp 660ffrt_function_header_t* queue_attr::callback() const; 661``` 662 663返回值 664 665- 返回任务执行器的指针,描述了该CPU任务如何执行和销毁。 666 667描述 668 669- 获取当前属性中设置的超时回调函数。 670 671##### set queue max_concurrency 672 673```cpp 674queue_attr& queue_attr::max_concurrency(const int max_concurrency); 675``` 676 677参数 678 679- `max_concurrency`:最大并发数。 680 681返回值 682 683- 返回当前对象以支持链式调用。 684 685描述 686 687- 设置队列的最大并发数(仅支持并发队列)。 688 689##### get queue max_concurrency 690 691```cpp 692int queue_attr::max_concurrency() const; 693``` 694 695返回值 696 697- 返回当前最大并发数。 698 699描述 700 701- 获取当前属性中设置的最大并发数(仅支持并发队列)。 702 703##### set queue thread_mode 704 705```cpp 706queue_attr& queue_attr::thread_mode(bool mode) 707``` 708 709参数 710 711- `bool`设置队列任务运行方式(`true`以线程模式运行, `false`以协程模式运行)。 712 713返回值 714 715- 返回当前对象以支持链式调用。 716 717描述 718 719- 设置队列中的任务是以协程模式还是以线程模式运行。 720 721##### get queue thread_mode 722 723```cpp 724bool queue_attr::thread_mode() const 725``` 726 727返回值 728 729- `true`表示以线程模式运行,`false`表示以协程模式运行。 730 731描述 732 733- 获取队列中的任务是以协程模式还是以线程模式运行。 734 735#### 样例 736 737```cpp 738#include "ffrt/cpp/queue.h" 739 740int main() 741{ 742 int x = 0; 743 std::function<void()> callbackFunc = [&x]() { 744 x++; 745 }; 746 747 // 创建队列,可设置队列优先级,默认为 default 等级 748 ffrt::queue que1("test_1", ffrt::queue_attr().qos(ffrt::qos_utility)); 749 // 创建队列,可通过设置 timeout 打开队列任务超时监测(默认关闭) 750 // 超时会打印 Error 日志并执行用户设置的 callback(可选) 751 ffrt::queue que2("test_2", ffrt::queue_attr().timeout(1000).callback(callbackFunc)); 752 return 0; 753} 754``` 755 756### queue 757 758#### 声明 759 760```cpp 761class queue; 762``` 763 764#### 描述 765 766用于创建和管理队列,支持队列任务的提交、取消、等待和排队任务数量查询。 767 768#### 方法 769 770##### 队列创建 771 772```cpp 773queue(const char* name, const queue_attr& attr = {}); 774queue(const queue_type type, const char* name, const queue_attr& attr = {}); 775``` 776 777参数 778 779- `type`:队列类型(如`queue_serial`或`queue_concurrent`),省略此入参时默认是`queue_serial`。 780- `name`:队列名称。 781- `attr`:队列属性(可选)。 782 783描述 784 785- 构造函数,创建指定类型和名称的队列。 786 787##### submit 788 789```cpp 790void queue::submit(const std::function<void()>& func, const task_attr& attr = {}); 791void queue::submit(std::function<void()>&& func, const task_attr& attr = {}); 792``` 793 794参数 795 796- `func`:任务函数闭包,支持左值引用和右值引用两个版本。 797- `attr`:任务属性(可选)。 798 799描述 800 801- 提交一个任务到队列中。 802 803##### submit_h 804 805```cpp 806task_handle queue::submit_h(const std::function<void()>& func, const task_attr& attr = {}); 807task_handle queue::submit_h(std::function<void()>&& func, const task_attr& attr = {}); 808``` 809 810参数 811 812- `func`:任务函数闭包,支持左值引用和右值引用两个版本。 813- `attr`:任务属性(可选)。 814 815返回值 816 817- `task_handle`:返回任务句柄。 818 819描述 820 821- 提交一个任务到队列中,并返回任务句柄。 822 823##### submit_head 824 825```cpp 826void queue::submit_head(const std::function<void()>& func, const task_attr& attr = {}); 827void queue::submit_head(std::function<void()>&& func, const task_attr& attr = {}); 828``` 829 830参数 831 832- `func`:任务函数闭包,支持左值引用和右值引用两个版本。 833- `attr`:任务属性(可选)。 834 835描述 836 837- 提交一个任务到队列头部。 838 839##### submit_head_h 840 841```cpp 842task_handle queue::submit_head_h(const std::function<void()>& func, const task_attr& attr = {}); 843task_handle queue::submit_head_h(std::function<void()>&& func, const task_attr& attr = {}); 844``` 845 846参数 847 848- `func`:任务函数闭包,支持左值引用和右值引用两个版本。 849- `attr`:任务属性(可选)。 850 851返回值 852 853- `task_handle`:返回任务句柄。 854 855描述 856 857- 提交一个任务到队列头部,并返回任务句柄。 858 859##### cancel 860 861```cpp 862int queue::cancel(const task_handle& handle); 863``` 864 865参数 866 867- `handle`:任务句柄。 868 869返回值 870 871- 返回0表示成功,其他值表示失败。 872 873描述 874 875- 取消一个任务。 876 877##### wait 878 879```cpp 880void queue::wait(const task_handle& handle); 881``` 882 883参数 884 885- `handle`:任务句柄。 886 887描述 888 889- 等待一个任务。 890 891##### get_task_cnt 892 893```cpp 894uint64_t queue::get_task_cnt(); 895``` 896 897返回值 898 899- 此队列排队的任务数。 900 901描述 902 903- 获取在队列中排队等待的任务数量。 904 905##### get_main_queue 906 907```cpp 908static queue* queue::get_main_queue(); 909``` 910 911返回值 912 913- 主线程队列。 914 915描述 916 917- 获取主线程队列,用于FFRT线程与主线程通信。 918 919#### 样例 920 921```cpp 922#include "ffrt/cpp/queue.h" 923 924int main() 925{ 926 // 创建队列,可设置队列优先级,默认为 default 等级 927 ffrt::queue que("test_queue", ffrt::queue_attr().qos(ffrt::qos_utility)); 928 int x = 0; 929 // 提交串行任务 930 que.submit([&x] { x += 10; }); 931 // 提交串行任务,并返回任务句柄 932 ffrt::task_handle t1 = que.submit_h([&x] { x += 10; }); 933 // 提交串行任务,设置延时时间 1000us,并返回任务句柄 934 ffrt::task_handle t2 = que.submit_h([&x] { x += 10; }, ffrt::task_attr().delay(1000)); 935 // 等待指定任务执行完成 936 que.wait(t1); 937 // 取消句柄为 t2 的任务 938 que.cancel(t2); 939 940 return 0; 941} 942``` 943 944## 同步原语 945 946### mutex 947 948#### 声明 949 950```cpp 951class mutex; 952``` 953 954#### 描述 955 956- FFRT提供的类似`std::mutex`的性能实现。 957- 该功能能够避免传统的`std::mutex`在抢不到锁时陷入内核的问题,在使用得当的条件下将会有更好的性能。 958 959#### 方法 960 961##### try_lock 962 963```cpp 964bool mutex::try_lock(); 965``` 966 967返回值 968 969- 获取锁是否成功。 970 971描述 972 973- 尝试获取FFRT互斥锁。 974 975##### lock 976 977```cpp 978void mutex::lock(); 979``` 980 981描述 982 983- 获取FFRT互斥锁。 984 985##### unlock 986 987```cpp 988void mutex::unlock(); 989``` 990 991描述 992 993- 释放FFRT互斥锁。 994 995#### 样例 996 997```cpp 998#include <chrono> 999#include <thread> 1000#include "ffrt/cpp/sleep.h" 1001#include "ffrt/cpp/mutex.h" 1002#include "ffrt/cpp/task.h" 1003 1004int main() 1005{ 1006 int x = 0; 1007 int y = 0; 1008 ffrt::mutex lock; 1009 1010 auto thread1Func = [&]() { 1011 ffrt::submit([&]() { 1012 ffrt::this_task::sleep_for(std::chrono::milliseconds(10)); 1013 while (true) { 1014 if (lock.try_lock()) { 1015 lock.unlock(); 1016 return; 1017 } else { 1018 y++; 1019 ffrt::this_task::sleep_for(std::chrono::milliseconds(10)); 1020 } 1021 } 1022 }, {}, {}, ffrt::task_attr().name("t2")); 1023 ffrt::wait(); 1024 }; 1025 1026 auto thread2Func = [&]() { 1027 ffrt::submit([&]() { 1028 lock.lock(); 1029 ffrt::this_task::sleep_for(std::chrono::milliseconds(50)); 1030 x++; 1031 lock.unlock(); 1032 }, {}, {}, ffrt::task_attr().name("t1")); 1033 ffrt::wait(); 1034 }; 1035 1036 std::thread t1(thread1Func); 1037 std::thread t2(thread2Func); 1038 t1.join(); 1039 t2.join(); 1040 1041 return 0; 1042} 1043``` 1044 1045### shared_mutex 1046 1047#### 声明 1048 1049```cpp 1050class shared_mutex; 1051``` 1052 1053#### 描述 1054 1055- FFRT提供类似`std::shared_mutex`的性能实现,在使用中要区分读锁和写锁。 1056- 该功能能够避免传统的`std::shared_mutex`在进入睡眠后不释放线程的问题,在使用得当的条件下将会有更好的性能。 1057 1058#### 方法 1059 1060##### try_lock 1061 1062```cpp 1063bool shared_mutex::try_lock(); 1064``` 1065 1066返回值 1067 1068- 获取锁是否成功。 1069 1070描述 1071 1072- 尝试获取FFRT写锁。 1073 1074##### lock 1075 1076```cpp 1077void shared_mutex::lock(); 1078``` 1079 1080描述 1081 1082- 获取FFRT写锁。 1083 1084##### unlock 1085 1086```cpp 1087void shared_mutex::unlock(); 1088``` 1089 1090描述 1091 1092- 释放FFRT写锁。 1093 1094##### lock_shared 1095 1096```cpp 1097void shared_mutex::lock_shared(); 1098``` 1099 1100描述 1101 1102- 获取FFRT读锁。 1103 1104##### try_lock_shared 1105 1106```cpp 1107void shared_mutex::try_lock_shared(); 1108``` 1109 1110描述 1111 1112- 尝试获取FFRT读锁。 1113 1114##### unlock_shared 1115 1116```cpp 1117void shared_mutex::unlock_shared(); 1118``` 1119 1120描述 1121 1122- 释放FFRT读锁。 1123 1124#### 样例 1125 1126```cpp 1127#include <chrono> 1128#include "ffrt/cpp/task.h" 1129#include "ffrt/cpp/shared_mutex.h" 1130#include "ffrt/cpp/sleep.h" 1131 1132int main() 1133{ 1134 int x = 0; 1135 ffrt::shared_mutex smut; 1136 1137 ffrt::submit([&]() { 1138 smut.lock(); 1139 ffrt::this_task::sleep_for(std::chrono::milliseconds(10)); 1140 x++; 1141 smut.unlock(); 1142 }, {},{}); 1143 1144 ffrt::submit([&]() { 1145 ffrt::this_task::sleep_for(std::chrono::milliseconds(2)); 1146 smut.lock_shared(); 1147 smut.unlock(); 1148 }, {},{}); 1149 1150 ffrt::submit([&]() { 1151 ffrt::this_task::sleep_for(std::chrono::milliseconds(2)); 1152 if(smut.try_lock()){ 1153 x++: 1154 smut.unlock(); 1155 } 1156 }, {},{}); 1157 1158 ffrt::submit([&]() { 1159 ffrt::this_task::sleep_for(std::chrono::milliseconds(2)); 1160 if(smut.try_lock_shared()){ 1161 smut.unlock_shared(); 1162 } 1163 }, {},{}); 1164 1165 return 0; 1166} 1167``` 1168 1169### recursive_mutex 1170 1171#### 声明 1172 1173```cpp 1174class recursive_mutex; 1175``` 1176 1177#### 描述 1178 1179- FFRT提供的类似`std::recursive_mutex`的性能实现。 1180- 该功能能够避免传统的`std::recursive_mutex`在抢不到锁时陷入内核的问题,在使用得当的条件下将会有更好的性能。 1181 1182#### 方法 1183 1184##### try_lock 1185 1186```cpp 1187bool recursive_mutex::try_lock(); 1188``` 1189 1190返回值 1191 1192- 获取锁是否成功。 1193 1194描述 1195 1196- 尝试获取FFRT递归锁。 1197 1198##### lock 1199 1200```cpp 1201void recursive_mutex::lock(); 1202``` 1203 1204描述 1205 1206- 获取FFRT递归锁。 1207 1208##### unlock 1209 1210```cpp 1211bool recursive_mutex::unlock(); 1212``` 1213 1214描述 1215 1216- 释放FFRT递归锁。 1217 1218#### 样例 1219 1220```cpp 1221#include "ffrt/cpp/mutex.h" 1222#include "ffrt/cpp/task.h" 1223 1224int main() 1225{ 1226 ffrt::recursive_mutex lock; 1227 int sum = 0; 1228 ffrt::submit([&]() { 1229 lock.lock(); 1230 lock.try_lock(); 1231 sum++; 1232 lock.lock(); 1233 lock.try_lock(); 1234 sum++; 1235 lock.unlock(); 1236 lock.unlock(); 1237 lock.unlock(); 1238 lock.unlock(); 1239 }, {}, {}); 1240 ffrt::wait(); 1241 return 0; 1242} 1243``` 1244 1245### condition_variable 1246 1247#### 声明 1248 1249```cpp 1250enum class cv_status { no_timeout, timeout }; 1251 1252class condition_variable; 1253``` 1254 1255#### 描述 1256 1257- FFRT 提供的类似`std::condition_variable`的性能实现。 1258- 该接口只能在FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。 1259- 该功能能够避免传统的`std::condition_variable`在条件不满足时陷入内核的问题,在使用得当的条件下将会有更好的性能。 1260 1261#### 方法 1262 1263##### wait_until 1264 1265```cpp 1266template <typename Clock, typename Duration, typename Pred> 1267bool condition_variable::wait_until(std::unique_lock<mutex>& lk, const std::chrono::time_point<Clock, Duration>& tp, Pred&& pred) noexcept; 1268``` 1269 1270参数 1271 1272- `lk`:mutex互斥量。 1273- `tp`:等待时间。 1274- `pred`:检查是否等待函数。 1275 1276返回值 1277 1278- 是否满足判断条件。 1279 1280描述 1281 1282- 该方法用于在指定时间点之前,阻塞当前任务并等待一个条件变量的通知,直到满足给定的谓词(Predicate)或者超时。 1283 1284##### wait_for 1285 1286```cpp 1287template <typename Rep, typename Period, typename Pred> 1288bool condition_variable::wait_for(std::unique_lock<mutex>& lk, const std::chrono::duration<Rep, Period>& sleepTime, Pred&& pred); 1289``` 1290 1291参数 1292 1293- `lk`:mutex互斥量。 1294- `sleepTime`:等待时间。 1295- `pred`:检查是否等待函数。 1296 1297返回值 1298 1299- 是否满足判断条件。 1300 1301描述 1302 1303- 该方法用于在指定时间点之前,阻塞当前任务并等待一个条件变量的通知,直到满足给定的谓词(Predicate)或者超时。 1304 1305##### wait 1306 1307```cpp 1308template <typename Pred> 1309void condition_variable::wait(std::unique_lock<mutex>& lk, Pred&& pred); 1310``` 1311 1312参数 1313 1314- `lk`:mutex互斥量。 1315- `pred`:检查是否等待函数。 1316 1317描述 1318 1319- 该方法用于等待某个条件变量的通知,直到满足给定的谓词(Predicate)。 1320 1321##### notify_one 1322 1323```cpp 1324void condition_variable::notify_one() noexcept; 1325``` 1326 1327描述 1328 1329- 该方法用于通知一个正在等待该条件变量的线程,唤醒它继续执行。具体哪个线程被唤醒,由操作系统的调度器决定。 1330 1331##### notify_all 1332 1333```cpp 1334void condition_variable::notify_all() noexcept; 1335``` 1336 1337描述 1338 1339- 该方法用于通知所有正在等待该条件变量的线程,唤醒它继续执行。这些线程会争夺获取锁并继续执行。 1340 1341#### 样例 1342 1343```cpp 1344#include <chrono> 1345#include <unistd.h> 1346#include <thread> 1347#include "ffrt/cpp/condition_variable.h" 1348#include "ffrt/cpp/mutex.h" 1349#include "ffrt/cpp/task.h" 1350 1351int main() 1352{ 1353 const int sleepTime = 50 * 1000; 1354 const int checkDelayTime = 10 * 1000; 1355 const std::chrono::milliseconds waitTime = std::chrono::milliseconds(100); 1356 ffrt::condition_variable cond; 1357 ffrt::mutex lock_; 1358 int val = 0; 1359 int predVal = 0; 1360 const int lastVal = 2; 1361 1362 auto threadWaitFunc = [&]() { 1363 std::unique_lock<ffrt::mutex> lck(lock_); // 使用 std::mutex 1364 cond.wait_until(lck, std::chrono::steady_clock::now() + waitTime, [&] { return predVal == 1; }); 1365 val = lastVal; 1366 }; 1367 1368 auto threadNotifyFunc = [&]() { 1369 val = 1; 1370 usleep(sleepTime); 1371 predVal = 1; 1372 cond.notify_one(); 1373 }; 1374 1375 std::thread tWait(threadWaitFunc); 1376 std::thread tNotify(threadNotifyFunc); 1377 tWait.join(); 1378 tNotify.join(); 1379 usleep(checkDelayTime); 1380 return 0; 1381} 1382``` 1383 1384## 阻塞原语 1385 1386### sleep 1387 1388#### 描述 1389 1390- FFRT提供的类似`std::this_thread::sleep_for`和`std::this_thread::sleep_until`的性能实现。 1391- 该接口只能在FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。 1392- 该功能能够避免传统的`std::this_thread::sleep_for`睡眠时陷入内核的问题,在使用得当的条件下将会有更好的性能。 1393- 该接口调用后实际睡眠时长不小于配置值。 1394 1395#### 方法 1396 1397##### sleep_for 1398 1399```cpp 1400template <class _Rep, class _Period> 1401void this_task::sleep_for(const std::chrono::duration<_Rep, _Period>& d); 1402``` 1403 1404参数 1405 1406- `d`:要休眠的持续时间。 1407 1408描述 1409 1410- 该方法用于让当前任务休眠指定的持续时间。 1411 1412##### sleep_until 1413 1414```cpp 1415template<class _Clock, class _Duration> 1416void this_task::sleep_until( 1417 const std::chrono::time_point<_Clock, _Duration>& abs_time); 1418``` 1419 1420参数 1421 1422- `abs_time`:绝对时间点,表示任务应该被唤醒的目标时间。 1423 1424描述 1425 1426- 该方法用于让当前任务休眠直到指定的绝对时间点。 1427 1428#### 样例 1429 1430```cpp 1431#include "ffrt/cpp/sleep.h" 1432#include "ffrt/cpp/task.h" 1433 1434int main() 1435{ 1436 ffrt::submit([] { 1437 ffrt::this_task::sleep_for(std::chrono::milliseconds(2000)); 1438 }); 1439 ffrt::wait(); 1440 return 0; 1441} 1442``` 1443 1444## 协同原语 1445 1446### yield 1447 1448#### 声明 1449 1450```cpp 1451static void this_task::yield(); 1452``` 1453 1454#### 描述 1455 1456- 当前任务主动让出CPU执行资源,让其他可以被执行的任务先执行,如果没有其他可被执行的任务,`yield`无效。 1457- 该接口只能在FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。 1458- 此函数的确切行为取决于实现,特别是使用中的FFRT调度程序的机制和系统状态。 1459 1460#### 样例 1461 1462```cpp 1463#include "ffrt/cpp/sleep.h" 1464#include "ffrt/cpp/task.h" 1465 1466int main() 1467{ 1468 const std::chrono::milliseconds setTime = std::chrono::milliseconds(5); 1469 ffrt::submit([&]() { 1470 ffrt::this_task::yield(); 1471 ffrt::this_task::sleep_for(setTime); 1472 ffrt::submit([&]() { 1473 ffrt::this_task::sleep_for(setTime); 1474 ffrt::this_task::yield(); 1475 }, {}, {}); 1476 ffrt::wait(); 1477 }, {}, {}); 1478 1479 ffrt::submit([&]() { 1480 ffrt::this_task::sleep_for(setTime); 1481 ffrt::this_task::yield(); 1482 }, {}, {}); 1483 1484 ffrt::wait(); 1485 return 0; 1486} 1487``` 1488 1489## 任务伙伴 1490 1491### job_partner_attr 1492 1493#### 声明 1494 1495```cpp 1496struct job_partner_attr; 1497``` 1498 1499#### 描述 1500 1501`job_partner`创建时使用的属性设置,包括QoS、Worker控制等设置。 1502 1503#### 方法 1504 1505##### set qos 1506 1507```cpp 1508job_partner_attr& job_partner_attr::qos(qos q); 1509``` 1510 1511参数 1512 1513- `q`:用户指定的QoS等级。 1514 1515返回值 1516 1517- 返回当前对象以支持链式调用。 1518 1519描述 1520 1521- 设置`job_partner`执行时所使用的线程的的QoS等级。 1522 1523##### get qos 1524 1525```cpp 1526int job_partner_attr::qos() const; 1527``` 1528 1529返回值 1530 1531- 返回当前QoS等级。 1532 1533描述 1534 1535- 获取当前属性中设置的QoS等级。 1536 1537##### set max_num 1538 1539```cpp 1540job_partner_attr& job_partner_attr::max_num(uint64_t v); 1541``` 1542 1543参数 1544 1545- `v`:用户指定的最大Worker数。 1546 1547返回值 1548 1549- 返回当前对象以支持链式调用。 1550 1551描述 1552 1553- 设置最大Worker数,以控制最多使用多少个Worker线程与master线程协同工作。 1554 1555##### get max_num 1556 1557```cpp 1558uint64_t job_partner_attr::max_num() const; 1559``` 1560 1561返回值 1562 1563- 返回最大Worker数。 1564 1565描述 1566 1567- 获取当前属性中设置的最大Worker数。 1568 1569##### set ratio 1570 1571```cpp 1572job_partner_attr& job_partner_attr::ratio(uint64_t v); 1573``` 1574 1575参数 1576 1577- `v`:用户指定的ratio参数。 1578 1579返回值 1580 1581- 返回当前对象以支持链式调用。 1582 1583描述 1584 1585- 设置ratio参数,用于控制Worker数量。ratio表示任务数和Worker数的比例。 1586 1587##### get ratio 1588 1589```cpp 1590uint64_t job_partner_attr::ratio() const; 1591``` 1592 1593返回值 1594 1595- 返回用户指定的ratio参数。 1596 1597描述 1598 1599- 获取当前属性中设置的ratio参数。 1600 1601##### set threshold 1602 1603```cpp 1604job_partner_attr& job_partner_attr::threshold(uint64_t v); 1605``` 1606 1607参数 1608 1609- `v`:用户指定的threshold参数。 1610 1611返回值 1612 1613- 返回当前对象以支持链式调用。 1614 1615描述 1616 1617- 设置threshold参数,用于控制Worker数量。threshold表示任务堆积到指定数量之后才会启动Worker,用于任务粒度非常小时避免Worker被频繁唤醒。 1618 1619##### get threshold 1620 1621```cpp 1622uint64_t job_partner_attr::threshold() const; 1623``` 1624 1625返回值 1626 1627- 返回用户指定的threshold参数。 1628 1629描述 1630 1631- 获取当前属性中设置的threshold参数。 1632 1633##### set busy 1634 1635```cpp 1636job_partner_attr& job_partner_attr::busy(uint64_t us); 1637``` 1638 1639参数 1640 1641- `us`:繁忙重试的时长,单位是微秒。 1642 1643返回值 1644 1645- 返回当前对象以支持链式调用。 1646 1647描述 1648 1649- 设置Worker退出前的繁忙重试时间,在某些平台上会优化为低功耗模式,用于避免Worker频繁创建和退出。 1650 1651##### get busy 1652 1653```cpp 1654uint64_t job_partner_attr::busy() const; 1655``` 1656 1657返回值 1658 1659- 返回Worker退出前的繁忙重试时间。 1660 1661描述 1662 1663- 获取当前属性中设置的Worker退出前的繁忙重试时间。 1664 1665##### set queue_depth 1666 1667```cpp 1668job_partner_attr& job_partner_attr::queue_depth(uint64_t depth); 1669``` 1670 1671参数 1672 1673- `depth`:用户指定的任务队列深度。 1674 1675返回值 1676 1677- 返回当前对象以支持链式调用。 1678 1679描述 1680 1681- 设置任务队列深度,当设置为非二的幂次方时,会扩大为二的幂次方数。 1682 1683##### get queue_depth 1684 1685```cpp 1686uint64_t job_partner_attr::queue_depth() const; 1687``` 1688 1689返回值 1690 1691- 返回任务队列深度。 1692 1693描述 1694 1695- 获取当前属性中设置的任务队列深度。 1696 1697### job_partner 1698 1699#### 声明 1700 1701```cpp 1702template <int UsageId = 0> 1703struct job_partner; 1704``` 1705 1706#### 描述 1707 1708`job_partner`实例,基于该类的方法可以实现partner线程与master线程协同完成计算。 1709 1710UsageId表示`job_partner`实例的不同用途。 1711 1712#### 方法 1713 1714##### get_partner_of_this_thread 1715 1716```cpp 1717static auto& job_partner::get_partner_of_this_thread(const ffrt::job_partner_attr& attr = {}); 1718``` 1719 1720参数 1721 1722- `attr`:用户指定的`job_partner`属性。 1723 1724返回值 1725 1726- 返回当前线程的伙伴。 1727 1728描述 1729 1730- 该方法为`job_partner`的静态方法,用于获取当前线程伙伴(即`job_partner`实例)。 1731- 同一调用线程和同一`UsageId`唯一对应一个`job_partner`实例,即: 1732 - 同一线程不同`UsageId`的`job_partner`调用该方法返回的`job_partner`实例是不相干的; 1733 - 不同线程上同一`UsageId`的`job_partner`调用该方法返回的`job_partner`实例也是不相干的。 1734 1735##### submit suspendable job 1736 1737```cpp 1738template <bool boost = true> 1739int job_partner::submit(std::function<void()>&& suspendable_job, void* stack, size_t stack_size); 1740``` 1741 1742参数 1743 1744- `boost`:可选参数,是否触发Worker按水线自动扩容。 1745- `suspendable_job`:任务闭包。 1746- `stack`:任务执行的栈空间起始地址。 1747- `stack_size`:任务执行的栈的大小,和stack参数匹配。 1748 1749返回值 1750 1751- 提交成功时返回`ffrt_success`,否则返回`ffrt_error`,通常原因为`stack`为空或`stack_size`不满足最小栈空间(不同平台存在差异)限制,建议设置4KB以上的栈空间。 1752 1753描述 1754 1755- 提交一个可被暂停的任务,当在`suspendable_job`任务闭包中调用`submit_to_master`时,会暂停当前任务,并将`submit_to_master`入参中的闭包发回`job_partner`对应的master线程执行,直到master线程执行完闭包之后才恢复当前任务的执行。 1756 1757##### submit non_suspendable job 1758 1759```cpp 1760template <bool boost = true> 1761void job_partner::submit(std::function<void()>&& non_suspendable_job); 1762``` 1763 1764参数 1765 1766- `boost`:可选参数,是否触发Worker按水线自动扩容。 1767- `job`:任务闭包。 1768 1769描述 1770 1771- 提交一个不可暂停的普通任务,即在`non_suspendable_job`任务闭包中不应该调用`submit_to_master`,若强行调用`submit_to_master`,并不会暂停当前任务的执行,而是直接执行`submit_to_master`入参中的闭包。 1772 1773##### submit_to_master 1774 1775```cpp 1776static void job_partner::submit_to_master(std::function<void()>&& job); 1777``` 1778 1779参数 1780 1781- `job`:任务闭包。 1782 1783描述 1784 1785- 该方法为静态方法,在不同的线程上执行该方法效果不同。 1786- 若在partner线程上执行该方法,则会暂停当前正在执行的任务,并提交submit_to_master入参中的job任务发到对应的master线程执行,直到master线程执行完该闭包之后才恢复当前任务的执行。 1787- 在`suspendable job`内部,且在partner线程上执行调用该函数时才会将将job发到master线程执行,否则会在`submit_to_master`函数内部直接执行job闭包。 1788 1789##### wait 1790 1791```cpp 1792template<bool help_partner = true, uint64_t busy_wait_us = 100> 1793int job_partner::wait(); 1794``` 1795 1796参数 1797 1798- `help_partner`:当前等待线程是否帮助partner线程消费队列任务,从时延角度,设置为true会更优。 1799- `busy_wait_us`:如果`help_partner`设置为true,该参数无效,如果`help_partner`为false,当前等待线程在等待`busy_wait_us`之后会进入睡眠,直到任务完成才被唤醒。 1800 1801返回值 1802 1803- 等待成功时返回0,否则返回非0,通常原因为在非master线程上执行该函数。 1804 1805描述 1806 1807- 在master线程上调用该接口时,同步等待`job_partner`历史提交过的所有任务执行完成,并返回0。 1808 1809##### this_thread_is_master 1810 1811```cpp 1812static bool job_partner::this_thread_is_master(); 1813``` 1814 1815返回值 1816 1817- 当前线程是否为`this job_partner`的是master线程。 1818 1819描述 1820 1821- 该方法为非静态方法,判断当前线程是否为`this job_partner`的是master线程。 1822 1823#### 样例 1824 1825````cpp 1826#include <iostream> 1827#include <array> 1828#include <atomic> 1829#include "ffrt/ffrt.h" 1830 1831int main() 1832{ 1833 const int job_num = 100; 1834 constexpr uint64_t stack_size = 16 * 1024; 1835 std::array<char, stack_size> stack[job_num]; 1836 std::atomic<int> a = 0; 1837 auto partner = ffrt::job_partner<>::get_partner_of_this_thread(); 1838 for (int j = 0; j < job_num; j++) { 1839 partner->submit([&a] { 1840 a++; 1841 for (int i = 0; i < 100; i++) { 1842 ffrt::job_partner<>::submit_to_master([&a] { 1843 a++; 1844 }); 1845 } 1846 }, &stack[j], stack_size); 1847 } 1848 partner->wait(); 1849 std::cout << "a = " << a.load() << std::endl; // expect a = 10100 1850 return 0; 1851} 1852```` 1853