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 dependence[1]; 43dependence[0].type = ffrt_dependence_data; 44dependence[0].ptr = &x; 45ffrt_deps_t deps; 46deps.len = 1; 47deps.items = dependence; 48 49// 创建任务依赖 50ffrt_task_handle_t task = ffrt_submit_h_base(user_function_header, NULL, NULL, &attr); 51ffrt_dependence_t dependence[1]; 52dependence[0].type = ffrt_dependence_task; 53dependence[0].ptr = task; 54ffrt_deps_t deps; 55deps.len = 1; 56deps.items = 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 void foo(void* data) 360 { 361 printf("foo\n"); 362 } 363 364 void after_foo(void* data) 365 { 366 printf("after_foo\n"); 367 } 368 369 int main() 370 { 371 ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general); 372 373 func->exec = foo; 374 func->destroy = after_foo; 375 376 ffrt_submit_base(func, NULL, NULL, NULL); 377 ffrt_wait(); 378 379 return 0; 380 } 381 ``` 382 383- 样例2:生成一个带参数和返回值的任务执行体: 384 385 ```c 386 int foo(int x, int y) 387 { 388 printf("foo: x = %d, y = %d\n", x, y); 389 return x + y; 390 } 391 392 void after_foo(void* data) 393 { 394 printf("after_foo\n"); 395 } 396 397 // 用户自定义任务执行体,可携带参数和返回值 398 struct user_defined_function { 399 ffrt_function_header_t header; // 头部内存为ffrt_function_header_t 400 int arg1; // 参数1 401 int arg2; // 参数2 402 int ret; // 返回值 403 }; 404 405 // 将foo包装成void(*)(void*)的exec函数类型 406 void exec_func_wrapper(void* header) 407 { 408 user_defined_function* func = (user_defined_function*)header; 409 func->ret = foo(func->arg1, func->arg2); // 内部展开真正的foo函数,传递参数,获取返回值 410 } 411 412 int main() 413 { 414 user_defined_function* func = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general); 415 416 func->header.exec = exec_func_wrapper; 417 func->header.destroy = after_foo; 418 func->arg1 = 1; 419 func->arg2 = 2; 420 421 ffrt_submit_base((ffrt_function_header_t*)func, NULL, NULL, NULL); 422 ffrt_wait(); 423 424 printf("ret = %d\n", func->ret); 425 return 0; 426 } 427 ``` 428 429### ffrt_submit_base 430 431#### 声明 432 433```c 434FFRT_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); 435``` 436 437#### 参数 438 439- `f`:用户的任务执行体,可以是原生的`ffrt_function_header_t`类型,也可以基于`ffrt_function_header_t`自定义拓展类型。 440- `in_deps`:任务的输入数据依赖。输入数据依赖通常以实际数据的地址表达,也支持`ffrt_task_handle_t`作为一种特殊输入依赖。 441- `out_deps`:任务的输出数据依赖。输出数据依赖通常以实际数据的地址表达,不支持`ffrt_task_handle_t`。 442- `attr`:任务的属性设置。 443 444#### 描述 445 446提交一个普通任务,任务支持相关属性设置,在输入依赖解除后任务可调度执行,任务执行完成后解除输出依赖。 447 448#### 样例 449 450- 样例1:提交带属性的任务: 451 452 ```c 453 void foo(void* data) 454 { 455 printf("foo\n"); 456 } 457 458 void after_foo(void* data) 459 { 460 printf("after_foo\n"); 461 } 462 463 // 提交一个任务 464 ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general); 465 func->exec = foo; 466 func->destroy = after_foo; 467 ffrt_submit_base(func, NULL, NULL, NULL); 468 469 // 提交一个带属性的任务 470 ffrt_task_attr_t attr; 471 ffrt_task_attr_init(&attr); 472 ffrt_task_attr_set_name(&attr, "sample_task"); 473 ffrt_task_attr_set_qos(&attr, ffrt_qos_background); 474 ffrt_submit_base(func, NULL, NULL, &attr); 475 ``` 476 477- 样例2:提交带数据依赖的任务: 478 479 ```c 480 // 提交两个带数据依赖的任务,任务间存在Read-After-Write依赖关系 481 #include "math.h" 482 #include "ffrt.h" 483 484 void cos_func(float* x, float* y) 485 { 486 *y = std::cos(*x); 487 } 488 489 void tan_func(float* y, float* z) 490 { 491 *z = std::tan(*y); 492 } 493 494 struct user_defined_function { 495 ffrt_function_header_t header; 496 float* arg1; // 参数1 497 float* arg2; // 参数2 498 }; 499 500 void cos_func_wrapper(void* header) 501 { 502 user_defined_function* func = (user_defined_function*)header; 503 cos_func(func->arg1, func->arg2); 504 } 505 506 void tan_func_wrapper(void* header) 507 { 508 user_defined_function* func = (user_defined_function*)header; 509 tan_func(func->arg1, func->arg2); 510 } 511 512 void destroy(void* header) {} 513 514 int main() 515 { 516 float x = 0.5f, y, z; 517 518 user_defined_function* func1 = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general); 519 func1->header.exec = cos_func_wrapper; 520 func1->header.destroy = destroy; 521 func1->arg1 = &x; 522 func1->arg2 = &y; 523 524 user_defined_function* func2 = (user_defined_function*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general); 525 func2->header.exec = tan_func_wrapper; 526 func2->header.destroy = destroy; 527 func2->arg1 = &y; 528 func2->arg2 = &z; 529 530 ffrt_dependence_t dependence_x[1]; 531 dependence_x[0].type = ffrt_dependence_data; 532 dependence_x[0].ptr = &x; 533 ffrt_deps_t deps_x; 534 deps_x.len = 1; 535 deps_x.items = dependence_x; 536 ffrt_dependence_t dependence_y[1]; 537 dependence_y[0].type = ffrt_dependence_data; 538 dependence_y[0].ptr = &y; 539 ffrt_deps_t deps_y; 540 deps_y.len = 1; 541 deps_y.items = dependence_y; 542 ffrt_dependence_t dependence_z[1]; 543 dependence_z[0].type = ffrt_dependence_data; 544 dependence_z[0].ptr = &z; 545 ffrt_deps_t deps_z; 546 deps_z.len = 1; 547 deps_z.items = dependence_z; 548 549 ffrt_submit_base((ffrt_function_header_t*)func1, &deps_x, &deps_y, NULL); 550 ffrt_submit_base((ffrt_function_header_t*)func2, &deps_y, &deps_z, NULL); 551 552 ffrt_wait(); 553 printf("x = %f, y = %f, z = %f\n", x, y, z); 554 return 0; 555 } 556 ``` 557 558### ffrt_submit_h_base 559 560#### 声明 561 562```c 563typedef void* ffrt_task_handle_t; 564 565FFRT_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); 566``` 567 568#### 参数 569 570- `f`:用户的任务执行体,可以是原生的`ffrt_function_header_t`类型,也可以基于`ffrt_function_header_t`自定义拓展类型。 571- `in_deps`:任务的输入数据依赖。输入数据依赖通常以实际数据的地址表达,也支持`ffrt_task_handle_t`作为一种特殊输入依赖。 572- `out_deps`:任务的输出数据依赖。输出数据依赖通常以实际数据的地址表达,不支持`ffrt_task_handle_t`。 573- `attr`:任务的属性设置。 574 575#### 返回值 576 577- `ffrt_task_handle_t`任务的句柄。 578 579#### 描述 580 581相比于`ffrt_submit_base`接口,增加了任务句柄的返回值。 582 583#### 样例 584 585```c 586// 提交一个任务,获取任务句柄 587ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general); 588func->exec = foo; 589func->destroy = after_foo; 590ffrt_task_handle_t t = ffrt_submit_h_base(func, NULL, NULL, NULL); 591// 注意C API的ffrt_task_handle_t需要用户调用ffrt_task_handle_destroy显式销毁 592ffrt_task_handle_destroy(t); 593``` 594 595### ffrt_task_handle_inc_ref 596 597#### 声明 598 599```c 600FFRT_C_API uint32_t ffrt_task_handle_inc_ref(ffrt_task_handle_t handle); 601``` 602 603#### 参数 604 605- `handle`:任务句柄。 606 607#### 返回值 608 609- 任务的引用计数。 610 611#### 描述 612 613通过任务句柄增加对应任务的引用计数,每次调用引用计数加一。用于控制任务的生命周期使用,当引用计数不为零时,对应的任务资源不会被释放。注意`ffrt_submit_h_base`返回的`ffrt_task_handle_t`默认已有一个引用计数。通过`ffrt_task_handle_destroy`销毁`ffrt_task_handle_t`时默认减去一个引用计数。 614 615### ffrt_task_handle_dec_ref 616 617#### 声明 618 619```c 620FFRT_C_API uint32_t ffrt_task_handle_dec_ref(ffrt_task_handle_t handle); 621``` 622 623#### 参数 624 625- `handle`:任务句柄。 626 627#### 返回值 628 629- 任务的引用计数。 630 631#### 描述 632 633通过任务句柄减去对应任务的引用计数,每次调用引用计数减一。 634 635### ffrt_task_handle_destroy 636 637#### 声明 638 639```c 640FFRT_C_API void ffrt_task_handle_destroy(ffrt_task_handle_t handle); 641``` 642 643#### 参数 644 645- `handle`:任务句柄。 646 647#### 描述 648 649销毁任务句柄,同时默认减去一个任务引用计数。 650 651### ffrt_wait 652 653#### 声明 654 655```c 656FFRT_C_API void ffrt_wait(void); 657``` 658 659#### 描述 660 661同步等待所有前序提交的同级任务完成。 662 663#### 样例 664 665```c 666// 同步三个任务完成 667ffrt_submit_base(func1, NULL, NULL, NULL); 668ffrt_submit_base(func2, NULL, NULL, NULL); 669ffrt_submit_base(func3, NULL, NULL, NULL); 670ffrt_wait(); 671``` 672 673### ffrt_wait_deps 674 675#### 声明 676 677```c 678FFRT_C_API void ffrt_wait_deps(const ffrt_deps_t* deps); 679``` 680 681#### 参数 682 683- `deps`:需要同步的数据依赖。 684 685#### 描述 686 687同步对应的数据依赖解除。 688 689#### 样例 690 691```c 692// 构建x的数据依赖 693int x = 0; 694ffrt_dependence_t dependence[1]; 695dependence[0].type = ffrt_dependence_data; 696dependence[0].ptr = &x; 697ffrt_deps_t deps; 698deps.len = 1; 699deps.items = dependence; 700 701// 提交一个写任务 702ffrt_submit_base(func, NULL, &deps, NULL); 703 704// 同步写任务解除数据依赖 705ffrt_wait_deps(&deps); 706``` 707 708### ffrt_set_worker_stack_size 709 710#### 声明 711 712```c 713FFRT_C_API ffrt_error_t ffrt_set_worker_stack_size(ffrt_qos_t qos, size_t stack_size); 714``` 715 716#### 参数 717 718- `qos`:QoS等级。 719- `stack_size`:Worker线程栈大小,单位是字节。 720 721#### 返回值 722 723- 错误码 724 725#### 描述 726 727在开始提交任务前,设置某一组QoS的Worker线程栈大小(Worker线程按QoS分组,组间互不影响,组内线程属性相同)。通常该接口用于用户提交非协程任务且函数栈超过默认上限的场景,不设置时线程栈和OS默认规格一致。 728 729#### 样例 730 731```c 732// 把qos_default的Worker线程组的线程栈大小设置成2MB 733ffrt_error_t ret = ffrt_set_worker_stack_size(ffrt_qos_default, 2 * 1024 * 1024); 734``` 735 736### ffrt_this_task_update_qos 737 738#### 声明 739 740```c 741FFRT_C_API int ffrt_this_task_update_qos(ffrt_qos_t qos); 742``` 743 744#### 参数 745 746- `qos`:QoS等级。 747 748#### 返回值 749 750- 0表示成功,1表示失败。 751 752#### 描述 753 754在任务执行过程中,动态修改任务的QoS等级。注意该接口在任务的函数闭包内使用,修改的是当前正在执行的任务的QoS等级,接口调用会使任务先挂起一次再恢复执行。 755 756#### 样例 757 758```c 759// 一个qos_background的任务执行过程中动态修改QoS等级 760ffrt::submit([]() { 761 ... 762 int ret = ffrt_this_task_update_qos(ffrt_qos_user_initiated); 763 ... 764}, ffrt::task_attr().qos(ffrt::qos_background)); 765``` 766 767### ffrt_this_task_get_qos 768 769#### 声明 770 771```c 772FFRT_C_API ffrt_qos_t ffrt_this_task_get_qos(void); 773``` 774 775#### 返回值 776 777- QoS等级。 778 779#### 描述 780 781获取当前正在执行任务的QoS等级。 782 783#### 样例 784 785```c 786// 一个任务执行过程中动态获取其QoS等级 787ffrt::submit([]() { 788 ... 789 // 获取的qos等于ffrt_qos_background 790 ffrt_qos_t qos = ffrt_this_task_get_qos(); 791 ... 792}, ffrt::task_attr().qos(ffrt::qos_background)); 793``` 794 795### ffrt_this_task_get_id 796 797#### 声明 798 799```c 800FFRT_C_API uint64_t ffrt_this_task_get_id(void); 801``` 802 803#### 返回值 804 805- 任务的id。 806 807#### 描述 808 809获取当前正在执行任务的id。 810 811#### 样例 812 813```c 814// 一个任务执行过程中动态获取其任务id 815ffrt::submit([]() { 816 ... 817 // 获取的唯一任务id 818 uint64_t task_id = ffrt_this_task_get_id(); 819 ... 820}, ffrt::task_attr().qos(ffrt::qos_background)); 821``` 822 823### ffrt_task_handle_get_id 824 825#### 声明 826 827```c 828FFRT_C_API uint64_t ffrt_task_handle_get_id(ffrt_task_handle_t handle); 829``` 830 831#### 参数 832 833- `handle`:任务句柄。 834 835#### 返回值 836 837- 任务的id。 838 839#### 描述 840 841获取任务句柄对应的任务id。 842 843#### 样例 844 845```c 846ffrt_function_header_t* func = (ffrt_function_header_t*)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_general); 847func->exec = foo; 848func->destroy = after_foo; 849ffrt_task_handle_t t = ffrt_submit_h_base(func, NULL, NULL, NULL); 850// 通过句柄获取任务对应的id 851uint64_t task_id = ffrt_task_handle_get_id(t); 852ffrt_task_handle_destroy(t); 853``` 854 855## 任务队列 856 857### ffrt_queue_attr_t 858 859#### 声明 860 861```c 862typedef struct { 863 uint32_t storage[(ffrt_queue_attr_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)]; 864} ffrt_queue_attr_t; 865``` 866 867#### 描述 868 869用于配置队列的属性,如 QoS、超时时间、回调函数和最大并发数。 870 871#### 方法 872 873##### ffrt_queue_attr_init 874 875```c 876int ffrt_queue_attr_init(ffrt_queue_attr_t* attr) 877``` 878 879参数 880 881- `attr`:队列属性指针。 882 883返回值 884 885- 返回0表示成功,其他值表示失败。 886 887描述 888 889- 初始化队列属性对象。 890 891##### ffrt_queue_attr_destroy 892 893```c 894void ffrt_queue_attr_destroy(ffrt_queue_attr_t* attr) 895``` 896 897参数 898 899- `attr`:队列属性指针。 900 901描述 902 903- 销毁队列属性对象。 904 905##### ffrt_queue_attr_set_qos 906 907```c 908void ffrt_queue_attr_set_qos(ffrt_queue_attr_t* attr, ffrt_qos_t qos) 909``` 910 911参数 912 913- `attr`:队列属性指针。 914- `qos`:QoS等级。 915 916描述 917 918- 设置队列的QoS等级。 919 920##### ffrt_queue_attr_get_qos 921 922```c 923ffrt_qos_t ffrt_queue_attr_get_qos(const ffrt_queue_attr_t* attr) 924``` 925 926参数 927 928- `attr`:队列属性指针。 929 930返回值 931 932- 返回当前QoS等级。 933 934描述 935 936- 获取当前属性中设置的QoS等级。 937 938##### ffrt_queue_attr_set_timeout 939 940```c 941void ffrt_queue_attr_set_timeout(ffrt_queue_attr_t* attr, uint64_t timeout_us) 942``` 943 944参数 945 946- `attr`:队列属性指针。 947- `timeout_us`:超时时间(微秒)。 948 949描述 950 951- 设置队列的超时时间(以微秒为单位)。 952 953##### ffrt_queue_attr_get_timeout 954 955```c 956uint64_t ffrt_queue_attr_get_timeout(const ffrt_queue_attr_t* attr) 957``` 958 959参数 960 961- `attr`:队列属性指针。 962 963返回值 964 965- 返回当前超时阈值(微秒)。 966 967描述 968 969- 获取当前属性中设置的超时时间。 970 971##### ffrt_queue_attr_set_callback 972 973```c 974void ffrt_queue_attr_set_callback(ffrt_queue_attr_t* attr, ffrt_function_header_t* f) 975``` 976 977参数 978 979- `attr`:队列属性指针。 980- `f`:是任务执行器的指针,描述了该CPU任务如何执行和销毁。 981 982描述 983 984- 设置检测到队列任务超时后执行的回调函数。 985 986##### ffrt_queue_attr_get_callback 987 988```c 989ffrt_function_header_t* ffrt_queue_attr_get_callback(const ffrt_queue_attr_t* attr) 990``` 991 992参数 993 994- `attr`:队列属性指针。 995 996返回值 997 998- 返回任务执行器的指针,描述了该CPU任务如何执行和销毁。 999 1000描述 1001 1002- 获取当前属性中设置的超时回调函数。 1003 1004##### ffrt_queue_attr_set_max_concurrency 1005 1006```c 1007void ffrt_queue_attr_set_max_concurrency(ffrt_queue_attr_t* attr, const int max_concurrency) 1008``` 1009 1010参数 1011 1012- `attr`:队列属性指针。 1013- `max_concurrency`:最大并发数。 1014 1015描述 1016 1017- 设置队列的最大并发数(仅支持并发队列)。 1018 1019##### ffrt_queue_attr_get_max_concurrency 1020 1021```c 1022int ffrt_queue_attr_get_max_concurrency(const ffrt_queue_attr_t* attr) 1023``` 1024 1025参数 1026 1027- `attr`:队列属性指针。 1028 1029返回值 1030 1031- 返回当前最大并发数。 1032 1033描述 1034 1035- 获取当前属性中设置的最大并发数(仅支持并发队列)。 1036 1037#### 样例 1038 1039```c 1040#include <stdio.h> 1041#include "ffrt.h" 1042 1043using namespace ffrt; 1044using namespace std; 1045 1046int main(int narg, char** argv) 1047{ 1048 ffrt_queue_attr_t queue_attr; 1049 // 初始化队列属性,必需 1050 int result = ffrt_queue_attr_init(&queue_attr); 1051 1052 ffrt_queue_attr_set_qos(&queue_attr, static_cast<int>(ffrt_qos_utility)); 1053 1054 ffrt_queue_attr_set_timeout(&queue_attr, 10000); 1055 1056 ffrt_queue_attr_set_callback(&queue_attr, ffrt::create_function_wrapper(basicFunc, ffrt_function_kind_queue)); 1057 1058 int x = 0; 1059 std::function<void()>&& basicFunc = [&x]() { x += 1; }; 1060 ffrt_function_header_t* func = ffrt_queue_attr_get_callback(&queue_attr); 1061 1062 // 销毁队列属性,必需 1063 ffrt_queue_attr_destroy(&queue_attr); 1064} 1065``` 1066 1067### ffrt_queue_t 1068 1069#### 声明 1070 1071```c 1072typedef void* ffrt_queue_t; 1073``` 1074 1075#### 描述 1076 1077队列指针,提供一系列C接口支持队列任务的提交、取消、等待和排队任务数量查询。 1078 1079#### 方法 1080 1081##### ffrt_queue_create 1082 1083```c 1084ffrt_queue_t ffrt_queue_create(ffrt_queue_type_t type, const char* name, const ffrt_queue_attr_t* attr) 1085``` 1086 1087参数 1088 1089- `type`:队列类型(如`ffrt_queue_serial`或`ffrt_queue_concurrent`)。 1090- `name`:队列名称。 1091- `attr`:队列属性。 1092 1093返回值 1094 1095- `ffrt_queue_t`:成功则返回一个非空的队列句柄;否则返回空指针。 1096 1097描述 1098 1099- 创建指定类型和名称的队列。 1100 1101##### ffrt_queue_destroy 1102 1103```c 1104void ffrt_queue_destroy(ffrt_queue_t queue) 1105``` 1106 1107参数 1108 1109- `queue`:队列的句柄。 1110 1111描述 1112 1113- 销毁一个队列。 1114 1115##### ffrt_queue_submit 1116 1117```c 1118void ffrt_queue_submit(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr) 1119``` 1120 1121参数 1122 1123- `queue`:队列的句柄。 1124- `f`:任务执行器的指针,描述了该CPU任务如何执行和销毁。 1125- `attr`:任务属性。 1126 1127描述 1128 1129- 提交任务到队列中。 1130 1131##### ffrt_queue_submit_h 1132 1133```c 1134ffrt_task_handle_t ffrt_queue_submit_h(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr) 1135``` 1136 1137参数 1138 1139- `queue`:队列的句柄。 1140- `f`:任务执行器的指针,描述了该CPU任务如何执行和销毁。 1141- `attr`:任务属性。 1142 1143返回值 1144 1145- `ffrt_task_handle_t`:成功则返回一个非空的任务句柄;否则返回空指针。 1146 1147描述 1148 1149- 提交任务到队列中,并返回任务句柄。 1150 1151##### ffrt_queue_submit_head 1152 1153```c 1154void ffrt_queue_submit_head(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr); 1155``` 1156 1157参数 1158 1159- `queue`:队列的句柄。 1160- `f`:任务执行器的指针,描述了该CPU任务如何执行和销毁。 1161- `attr`:任务属性。 1162 1163描述 1164 1165- 提交任务到队列头部。 1166 1167##### ffrt_queue_submit_head_h 1168 1169```c 1170ffrt_task_handle_t ffrt_queue_submit_head_h(ffrt_queue_t queue, ffrt_function_header_t* f, const ffrt_task_attr_t* attr); 1171``` 1172 1173参数 1174 1175- `queue`:队列的句柄。 1176- `f`:任务执行器的指针,描述了该CPU任务如何执行和销毁。 1177- `attr`:任务属性。 1178 1179返回值 1180 1181- `ffrt_task_handle_t`:成功则返回一个非空的任务句柄;否则返回空指针。 1182 1183描述 1184 1185- 提交任务到队列头部,并返回任务句柄。 1186 1187##### ffrt_queue_wait 1188 1189```c 1190void ffrt_queue_wait(ffrt_task_handle_t handle) 1191``` 1192 1193参数 1194 1195- `ffrt_task_handle_t`:任务句柄。 1196 1197描述 1198 1199- 等待一个队列任务完成。 1200 1201##### ffrt_queue_cancel 1202 1203```c 1204int ffrt_queue_cancel(ffrt_task_handle_t handle) 1205``` 1206 1207参数 1208 1209- `ffrt_task_handle_t`:任务句柄。 1210 1211返回值 1212 1213- 返回0表示成功,其他值表示失败。 1214 1215描述 1216 1217- 取消一个队列任务。 1218 1219##### ffrt_get_main_queue 1220 1221```c 1222ffrt_queue_t ffrt_get_main_queue(); 1223``` 1224 1225返回值 1226 1227- 主线程队列。 1228 1229描述 1230 1231- 获取主线程队列,用于FFRT线程与主线程通信。 1232 1233##### ffrt_get_current_queue 1234 1235```c 1236ffrt_queue_t ffrt_get_current_queue(); 1237``` 1238 1239返回值 1240 1241- ArkTS Worker线程任务队列。 1242 1243描述 1244 1245- 此接口已于API 15版本后废弃,不建议继续使用。 1246- 获取ArkTS Worker线程队列,用于FFRT线程与ArkTS Worker线程通信。 1247 1248##### ffrt_queue_get_task_cnt 1249 1250```c 1251uint64_t ffrt_queue_get_task_cnt(ffrt_queue_t queue) 1252``` 1253 1254参数 1255 1256- `queue`:队列的句柄。 1257 1258返回值 1259 1260- 此队列排队的任务数。 1261 1262描述 1263 1264- 获取在队列中排队等待的任务数量。 1265 1266#### 样例 1267 1268```c 1269#include <stdio.h> 1270#include "ffrt.h" 1271 1272using namespace ffrt; 1273using namespace std; 1274 1275int main() 1276{ 1277 ffrt_queue_attr_t queue_attr; 1278 // 1、初始化队列属性,必需 1279 (void)ffrt_queue_attr_init(&queue_attr); 1280 1281 // 2、创建串行队列,并返回队列句柄 queue_handle 1282 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_serial, "test_queue", &queue_attr); 1283 1284 int result = 0; 1285 std::function<void()>&& basicFunc = [&result]() { result += 1; }; 1286 1287 // 3、提交串行任务 1288 ffrt_queue_submit(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr); 1289 1290 // 4、提交串行任务,并返回任务句柄 1291 ffrt_task_handle_t t1 = ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr); 1292 // 5、等待指定任务执行完成 1293 ffrt_queue_wait(t1); 1294 1295 ffrt_task_handle_t t2 = ffrt_queue_submit_h(queue_handle, create_function_wrapper(basicFunc, ffrt_function_kind_queue), nullptr); 1296 // 6、取消句柄为 t2 的任务 1297 int ret = ffrt_queue_cancel(t2); 1298 1299 // 7、销毁提交给串行队列任务的句柄 t1 和 t2,必需 1300 ffrt_task_handle_destroy(t1); 1301 ffrt_task_handle_destroy(t2); 1302 // 8、销毁队列属性,必需 1303 ffrt_queue_attr_destroy(&queue_attr); 1304 // 9、销毁队列句柄,必需 1305 ffrt_queue_destroy(queue_handle); 1306} 1307``` 1308 1309## 同步原语 1310 1311### ffrt_mutexattr_t 1312 1313#### 声明 1314 1315```c 1316typedef enum { 1317 ffrt_error = -1, 1318 ffrt_success = 0, 1319 ffrt_error_nomem = ENOMEM, 1320 ffrt_error_timedout = ETIMEDOUT, 1321 ffrt_error_busy = EBUSY, 1322 ffrt_error_inval = EINVAL 1323} ffrt_error_t; 1324 1325typedef enum { 1326 ffrt_mutex_normal = 0, 1327 ffrt_mutex_recursive = 2, 1328 ffrt_mutex_default = ffrt_mutex_normal 1329} ffrt_mutex_type; 1330 1331struct ffrt_mutexattr_t; 1332 1333int ffrt_mutexattr_init(ffrt_mutexattr_t* attr); 1334int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type); 1335int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type); 1336int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr); 1337``` 1338 1339#### 描述 1340 1341- FFRT提供的类似pthread mutexattr的性能实现。 1342 1343#### 方法 1344 1345##### ffrt_mutexattr_init 1346 1347```c 1348FFRT_C_API int ffrt_mutexattr_init(ffrt_mutexattr_t* attr); 1349``` 1350 1351参数 1352 1353- `attr`:FFRT锁属性。 1354 1355返回值 1356 1357- `attr`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1358 1359描述 1360 1361- 初始化`mutexattr`。 1362 1363##### ffrt_mutexattr_destroy 1364 1365```c 1366FFRT_C_API int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr); 1367``` 1368 1369参数 1370 1371- `attr`:FFRT锁属性。 1372 1373返回值 1374 1375- `attr`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1376 1377描述 1378 1379- 销毁mutexattr。 1380 1381##### ffrt_mutexattr_settype 1382 1383```c 1384FFRT_C_API int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type); 1385``` 1386 1387参数 1388 1389- `attr`:FFRT锁属性。 1390- `type`:FFRT锁类型,当前仅支持互斥锁`ffrt_mutex_normal`和递归锁`ffrt_mutex_recursive`。 1391 1392返回值 1393 1394- `attr`不为空且`type`有效返回`ffrt_success`,否则返回`ffrt_error_inval`。 1395 1396描述 1397 1398- 设置FFRT锁属性。 1399 1400##### ffrt_mutexattr_gettype 1401 1402```c 1403FFRT_C_API int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type); 1404``` 1405 1406参数 1407 1408- `attr`:FFRT锁属性。 1409- `type`:FFRT锁类型指针。 1410 1411返回值 1412 1413- `attr`和`type`均不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1414 1415描述 1416 1417- 获取FFRT锁属性。 1418 1419#### 样例 1420 1421```c 1422#include "ffrt.h" 1423 1424void ffrt_c_mutexattr_test() 1425{ 1426 ffrt_mutexattr_t attr; 1427 ffrt_mutex_t recursive_mtx; 1428 EXPECT_EQ(ffrt_mutexattr_init(nullptr), ffrt_error_inval); 1429 EXPECT_EQ(ffrt_mutexattr_settype(nullptr, -1), ffrt_error_inval); 1430 EXPECT_EQ(ffrt_mutexattr_gettype(nullptr, nullptr), ffrt_error_inval); 1431 EXPECT_EQ(ffrt_mutexattr_destroy(nullptr), ffrt_error_inval); 1432} 1433``` 1434 1435### ffrt_mutex_t 1436 1437- FFRT 提供的类似pthread mutex的性能实现,但不支持类似`PTHREAD_MUTEX_INITIALIZER`的初始化。 1438 1439#### 声明 1440 1441```c 1442typedef enum { 1443 ffrt_error = -1, 1444 ffrt_success = 0, 1445 ffrt_error_nomem = ENOMEM, 1446 ffrt_error_timedout = ETIMEDOUT, 1447 ffrt_error_busy = EBUSY, 1448 ffrt_error_inval = EINVAL 1449} ffrt_error_t; 1450 1451struct ffrt_mutex_t; 1452 1453struct ffrt_mutexattr_t; 1454 1455int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr); 1456int ffrt_mutex_lock(ffrt_mutex_t* mutex); 1457int ffrt_mutex_unlock(ffrt_mutex_t* mutex); 1458int ffrt_mutex_trylock(ffrt_mutex_t* mutex); 1459int ffrt_mutex_destroy(ffrt_mutex_t* mutex); 1460``` 1461 1462#### 描述 1463 1464- 该接口支持在FFRT任务内部调用,也支持在FFRT任务外部调用。 1465- 该接口能够避免pthread传统的`pthread_mutex_t`在抢不到锁时陷入内核态的问题,在使用得当的条件下将会有更好的性能。 1466- C API 中的`ffrt_mutexattr_t`需要用户调用`ffrt_mutexattr_init`和`ffrt_mutexattr_destroy`显示创建和销毁,否则其行为是未定义的。 1467- C API 中的`ffrt_mutex_t`需要用户调用`ffrt_mutex_init`和`ffrt_mutex_destroy`显式创建和销毁,否则其行为是未定义的。 1468- C API 中的`ffrt_mutex_t`对象的置空和销毁由用户完成,对同一个`ffrt_mutex_t`仅能调用一次`ffrt_mutex_destroy`,重复对同一个 ffrt_mutex_t 调用`ffrt_mutex_destroy`,其行为是未定义的。 1469- C API 中的同一个`ffrt_mutexattr_t`只能调用一次`ffrt_mutexattr_init`和`ffrt_mutexattr_destroy`,重复调用其行为是未定义的。 1470- 用户需要在调用`ffrt_mutex_init`之后和调用`ffrt_mutex_destroy`之前显示调用`ffrt_mutexattr_destroy`。 1471- 在`ffrt_mutex_destroy`之后再对`ffrt_mutex_t`进行访问,其行为是未定义的。 1472 1473#### 方法 1474 1475##### ffrt_mutex_init 1476 1477```c 1478FFRT_C_API int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr); 1479``` 1480 1481参数 1482 1483- `mutex`:指向所操作的锁指针。 1484- `attr`:FFRT锁属性,attr的有效值范围是:空指针或等于`ffrt_mutex_normal`代表互斥锁,`ffrt_mutex_recursive`代表递归锁。 1485 1486返回值 1487 1488- 如果`mutex`不为空且`attr`在有效值范围内返回`ffrt_success`,否则返回`ffrt_error_inval`。 1489 1490描述 1491 1492- 初始化FFRT锁。 1493 1494##### ffrt_mutex_destroy 1495 1496```c 1497FFRT_C_API int ffrt_mutex_destroy(ffrt_mutex_t* mutex); 1498``` 1499 1500参数 1501 1502- `mutex`:指向所操作的锁指针。 1503 1504返回值 1505 1506- `mutex`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1507 1508描述 1509 1510- 对指定的互斥锁/递归锁进行销毁操作。 1511 1512##### ffrt_mutex_lock 1513 1514```c 1515FFRT_C_API int ffrt_mutex_lock(ffrt_mutex_t* mutex); 1516``` 1517 1518参数 1519 1520- `mutex`:指向所操作的锁指针。 1521 1522返回值 1523 1524- `mutex`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1525 1526描述 1527 1528- 对指定的互斥锁/递归锁进行加锁操作,该方法会阻塞当前任务直到能成功获得锁。 1529 1530##### ffrt_mutex_unlock 1531 1532```c 1533FFRT_C_API int ffrt_mutex_unlock(ffrt_mutex_t* mutex); 1534``` 1535 1536参数 1537 1538- `mutex`:指向所操作的锁指针。 1539 1540返回值 1541 1542- `mutex`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1543 1544描述 1545 1546- 对指定的互斥锁/递归锁进行解锁操作。 1547 1548##### ffrt_mutex_trylock 1549 1550```c 1551FFRT_C_API int ffrt_mutex_trylock(ffrt_mutex_t* mutex); 1552``` 1553 1554参数 1555 1556- `mutex`:指向所操作的锁指针。 1557 1558返回值 1559 1560- `mutex`为空返回ffrt_error_inval,`mutex`不为空且持锁成功返回`ffrt_success`,`mutex`不为空且持锁失败返回`ffrt_error_busy`。 1561 1562描述 1563 1564- 对指定的互斥锁/递归锁进行尝试加锁操作。 1565 1566#### 样例 1567 1568```c 1569#include "ffrt.h" 1570 1571void ffrt_c_mutex_test() 1572{ 1573 ffrt_mutexattr_t attr; 1574 ffrt_mutex_t lock; 1575 int ret = 0; 1576 int sum = 0; 1577 int type = ffrt_mutex_default; 1578 ret = ffrt_mutexattr_init(&attr); 1579 EXPECT_EQ(ret, ffrt_success); 1580 ret = ffrt_mutexattr_settype(&attr, ffrt_mutex_recursive); 1581 EXPECT_EQ(ret, ffrt_success); 1582 ret = ffrt_mutexattr_gettype(&attr, &type); 1583 EXPECT_EQ(ret, ffrt_success); 1584 ret = ffrt_mutex_init(&lock, &attr); 1585 EXPECT_EQ(type, ffrt_mutex_recursive); 1586 ffrt::submit([&]() { 1587 ffrt_mutex_lock(&lock); 1588 EXPECT_EQ(ffrt_mutex_trylock(&lock), ffrt_success); 1589 sum++; 1590 ffrt_mutex_lock(&lock); 1591 EXPECT_EQ(ffrt_mutex_trylock(&lock), ffrt_success); 1592 sum++; 1593 ffrt_mutex_unlock(&lock); 1594 ffrt_mutex_unlock(&lock); 1595 ffrt_mutex_unlock(&lock); 1596 ffrt_mutex_unlock(&lock); 1597 }, {}, {}); 1598 1599 ffrt::wait(); 1600 1601 ffrt_mutexattr_destroy(&attr); 1602 ffrt_mutex_destroy(&lock); 1603} 1604``` 1605 1606### ffrt_cond_t 1607 1608- FFRT提供的类似pthread信号量的性能实现,但不支持类似`PTHREAD_COND_INITIALIZER`的初始化。 1609 1610#### 声明 1611 1612```c 1613typedef enum { 1614 ffrt_error = -1, 1615 ffrt_success = 0, 1616 ffrt_error_nomem = ENOMEM, 1617 ffrt_error_timedout = ETIMEDOUT, 1618 ffrt_error_busy = EBUSY, 1619 ffrt_error_inval = EINVAL 1620} ffrt_error_t; 1621 1622typedef struct { 1623 uint32_t storage[(ffrt_cond_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)]; 1624} ffrt_cond_t; 1625 1626int ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr); 1627int ffrt_cond_signal(ffrt_cond_t* cond); 1628int ffrt_cond_broadcast(ffrt_cond_t* cond); 1629int ffrt_cond_wait(ffrt_cond_t*cond, ffrt_mutex_t* mutex); 1630int ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point); 1631int ffrt_cond_destroy(ffrt_cond_t* cond); 1632``` 1633 1634#### 描述 1635 1636- 该接口支持在FFRT任务内部调用,也支持在FFRT任务外部调用。 1637- 该功能能够避免传统的`pthread_cond_t`在条件不满足时陷入内核的问题,在使用得当的条件下将会有更好的性能。 1638- 注意:C API 中的`ffrt_cond_t`需要用户调用`ffrt_cond_init`和`ffrt_cond_destroy`显式创建和销毁,而C++ API 中依赖构造和析构自动完成。 1639- 注意:C API 中的`ffrt_cond_t`对象的置空和销毁由用户完成,对同一个`ffrt_cond_t`仅能调用一次`ffrt_cond_destroy`,重复对同一个`ffrt_cond_t`调用`ffrt_cond_destroy`,其行为是未定义的。 1640- 注意:在`ffrt_cond_destroy`之后再对`ffrt_cond_t`进行访问,其行为是未定义的。 1641 1642#### 方法 1643 1644##### ffrt_cond_init 1645 1646```c 1647FFRT_C_API int ffrt_cond_init(ffrt_cond_t* cond, const ffrt_condattr_t* attr); 1648``` 1649 1650参数 1651 1652- `cond`:指向所操作的信号量的指针。 1653- `attr`:属性设定,空指针表示使用默认属性。 1654 1655返回值 1656 1657- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1658 1659描述 1660 1661- 初始化FFRT条件变量。 1662 1663##### ffrt_cond_destroy 1664 1665```c 1666FFRT_C_API int ffrt_cond_destroy(ffrt_cond_t* cond); 1667``` 1668 1669参数 1670 1671- `cond`:指向所操作的信号量的指针。 1672 1673返回值 1674 1675- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1676 1677描述 1678 1679- 销毁FFRT条件变量。 1680 1681##### ffrt_cond_signal 1682 1683```c 1684FFRT_C_API int ffrt_cond_signal(ffrt_cond_t* cond); 1685``` 1686 1687参数 1688 1689- `cond`:指向所操作的信号量的指针。 1690 1691返回值 1692 1693- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1694 1695描述 1696 1697- 该方法用于唤醒一个等待条件变量的任务。 1698 1699##### ffrt_cond_broadcast 1700 1701```c 1702FFRT_C_API int ffrt_cond_broadcast(ffrt_cond_t* cond); 1703``` 1704 1705参数 1706 1707- `cond`:指向所操作的信号量的指针。 1708 1709返回值 1710 1711- `cond`不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1712 1713描述 1714 1715- 该方法用于唤醒所有等待条件变量的任务。 1716 1717##### ffrt_cond_wait 1718 1719```c 1720FFRT_C_API int ffrt_cond_wait(ffrt_cond_t* cond, ffrt_mutex_t* mutex); 1721``` 1722 1723参数 1724 1725- `cond`:指向所操作的信号量的指针。 1726- `mutex`:指向要在阻塞期间解锁的互斥锁的指针。 1727 1728返回值 1729 1730- `cond`和`mutex`均不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1731 1732描述 1733 1734- 方法用于在条件变量上等待。任务在调用该方法时会释放传入的互斥量,并进入等待状态,直到另一个任务通知条件变量,才会重新获取互斥量并继续执行。 1735- 此方法通常与`ffrt_mutex_lock`或`ffrt_mutex_trylock`一起使用,确保在进入等待状态之前已经持有互斥量。 1736 1737##### ffrt_cond_timedwait 1738 1739```c 1740FFRT_C_API int ffrt_cond_timedwait(ffrt_cond_t* cond, ffrt_mutex_t* mutex, const struct timespec* time_point); 1741``` 1742 1743参数 1744 1745- `cond`:指向所操作的信号量的指针。 1746- `mutex`:指向要在阻塞期间解锁的互斥锁的指针。 1747- `time_point`:指向指定等待时限时间的对象的指针。 1748 1749返回值 1750 1751- `cond`和`mutex`和`time_point`均不为空返回`ffrt_success`,否则返回`ffrt_error_inval`。 1752 1753描述 1754 1755- 该方法用于在条件变量上等待,直到指定的超时时间到达。 1756- 与`ffrt_cond_wait`不同,`ffrt_cond_timedwait`方法允许任务在条件变量上等待一段时间,如果在指定时间内没有收到通知,任务将被唤醒该函数返回。 1757 1758#### 样例 1759 1760```c 1761#include "ffrt.h" 1762 1763void ffrt_c_cond_test() 1764{ 1765 int a = 0; 1766 ffrt_cond_t cond; 1767 ffrt_mutex_t lock_; 1768 ffrt_cond_init(&cond, nullptr); 1769 ffrt_mutex_init(&lock_, nullptr); 1770 1771 for (int i = 0; i < 3; i++) { 1772 ffrt::submit([&]() { 1773 int timeout = 2000; 1774 struct timespec tm = timeoutms_to_tm(timeout); 1775 ffrt_mutex_lock(&lock_); 1776 auto start = std::chrono::high_resolution_clock::now(); 1777 int ret = ffrt_cond_timedwait(&cond, &lock_, &tm); 1778 auto end = std::chrono::high_resolution_clock::now(); 1779 a = 123; 1780 ffrt_mutex_unlock(&lock_); 1781 std::chrono::duration<double, std::milli> elapsed = end-start; 1782 double t = elapsed.count(); 1783 std::cout << "ffrt_cond_timedwait " << t << " ms\n"; 1784 EXPECT_EQ(ret, ffrt_success); 1785 }, {}, {}); 1786 } 1787 1788 ffrt::submit([&]() { 1789 ffrt_usleep(1000 * 1000); 1790 ffrt_mutex_lock(&lock_); 1791 a = 5; 1792 ffrt_cond_broadcast(&cond); 1793 ffrt_mutex_unlock(&lock_); 1794 }, {}, {}); 1795 ffrt::wait(); 1796 ffrt_cond_destroy(&cond); 1797 ffrt_mutex_destroy(&lock_); 1798 EXPECT_EQ(a, 123); 1799} 1800``` 1801 1802## 阻塞原语 1803 1804### ffrt_usleep 1805 1806#### 声明 1807 1808```c 1809FFRT_C_API int ffrt_usleep(uint64_t usec); 1810``` 1811 1812#### 参数 1813 1814- `usec`:睡眠的微秒数。 1815 1816#### 描述 1817 1818- FFRT提供的类似C11 sleep和Linux usleep的性能实现。 1819- 该接口只能在FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。 1820- 该接口睡眠精度为微秒。 1821- 该功能能够避免传统的`sleep`睡眠时陷入内核的问题,在使用得当的条件下将会有更好的性能。 1822 1823#### 样例 1824 1825```c 1826#include "ffrt.h" 1827 1828void ffrt_c_usleep_test() 1829{ 1830 ffrt::submit([=]() { ffrt_usleep(10); }, {}, {}); 1831 ffrt::wait(); 1832} 1833``` 1834 1835## 协同原语 1836 1837### ffrt_yield 1838 1839#### 声明 1840 1841```c 1842FFRT_C_API void ffrt_yield(); 1843``` 1844 1845#### 描述 1846 1847- 当前任务主动让出CPU执行资源,允许其他可执行的任务运行,如果没有其他可执行的任务,`yield`无效。 1848- 该接口只能在 FFRT任务内部调用,在FFRT任务外部调用存在未定义的行为。 1849- 此函数的确切行为取决于实现,特别是使用中的FFRT调度程序的机制和系统状态。 1850 1851#### 样例 1852 1853```c 1854#include "ffrt.h" 1855 1856void ffrt_c_yield_test() 1857{ 1858 int count = 12; 1859 for (int i = 0; i < count; i++) { 1860 ffrt::submit( 1861 [&]() { 1862 ffrt_usleep(100); 1863 printf("test"); 1864 ffrt_yield(); 1865 }, 1866 {}, {}); 1867 } 1868 ffrt::wait(); 1869} 1870``` 1871 1872## 定时器 1873 1874### ffrt_timer_t 1875 1876#### 声明 1877 1878```c 1879typedef int ffrt_timer_t; 1880typedef void (*ffrt_timer_cb)(void* data); 1881``` 1882 1883#### 描述 1884 1885提供定时器相关的功能。 1886 1887#### 方法 1888 1889##### ffrt_timer_start 1890 1891声明 1892 1893```c 1894FFRT_C_API ffrt_timer_t ffrt_timer_start(ffrt_qos_t qos, uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat); 1895``` 1896 1897参数 1898 1899- `qos`:QoS等级。 1900- `timeout`:定时器时间,单位是毫秒。 1901- `cb`:到期后的回调函数。 1902- `data`:回调函数的输入参数。 1903- `repeat`:是否循环定时器。 1904 1905返回值 1906 1907- `ffrt_timer_t`定时器句柄。 1908 1909描述 1910 1911- 启动一个定时器,定时器到期且未被取消的话,执行回调函数。如果设置`repeat`为`true`,定时器到期后会重复设置。 1912 1913##### ffrt_timer_stop 1914 1915声明 1916 1917```c 1918FFRT_C_API int ffrt_timer_stop(ffrt_qos_t qos, ffrt_timer_t handle); 1919``` 1920 1921参数 1922 1923- `qos`:QoS等级。 1924- `handle`:定时器句柄。 1925 1926返回值 1927 1928- 0表示成功,-1表示失败。 1929 1930描述 1931 1932- 取消一个定时器,和`ffrt_timer_start`配对使用。 1933 1934#### 样例 1935 1936- 样例1:使用单次定时器: 1937 1938 ```c 1939 #include <stdint.h> 1940 #include <unistd.h> 1941 #include "ffrt.h" 1942 1943 static void test_fun(void *data) 1944 { 1945 *(int *)data += 1; 1946 } 1947 1948 void (*cb)(void *) = test_fun; 1949 1950 int main(int narg, char** argv) 1951 { 1952 static int x = 0; 1953 void *data = &x; 1954 uint64_t timeout = 200; 1955 // 启动定时器,在200ms后执行回调函数 1956 int handle = ffrt_timer_start(ffrt_qos_default, timeout, data, cb, false); 1957 usleep(300000); 1958 // 定时器已经执行,取消无效 1959 ffrt_timer_stop(ffrt_qos_default, handle); 1960 printf("data: %d\n", x); // x值变成1 1961 return 0; 1962 } 1963 ``` 1964 1965- 样例2:使用循环定时器: 1966 1967 ```c 1968 #include <stdint.h> 1969 #include <unistd.h> 1970 #include "ffrt.h" 1971 1972 static void test_fun(void *data) 1973 { 1974 *(int *)data += 1; 1975 } 1976 1977 void (*cb)(void *) = test_fun; 1978 1979 int main(int narg, char** argv) 1980 { 1981 static int x = 0; 1982 void *data = &x; 1983 uint64_t timeout = 200; 1984 // 启动循环定时器,每间隔200ms执行回调函数 1985 int handle = ffrt_timer_start(ffrt_qos_default, timeout, data, cb, true); 1986 usleep(500000); 1987 // 取消循环定时器 1988 ffrt_timer_stop(ffrt_qos_default, handle); 1989 printf("data: %d\n", x); // x的值变成2 1990 return 0; 1991 } 1992 ``` 1993 1994## 循环 1995 1996### ffrt_loop_t 1997 1998#### 声明 1999 2000```c 2001typedef void* ffrt_loop_t; 2002``` 2003 2004#### 描述 2005 2006提供循环相关的功能。 2007 2008#### 方法 2009 2010##### ffrt_loop_create 2011 2012声明 2013 2014```c 2015FFRT_C_API ffrt_loop_t ffrt_loop_create(ffrt_queue_t queue); 2016``` 2017 2018参数 2019 2020- `queue`:loop需要绑定一个FFRT并发队列使用。 2021 2022返回值 2023 2024- `ffrt_loop_t`对象。 2025 2026描述 2027 2028- 创建一个loop,需要绑定一个并发队列存储任务,用户可以向队列中提交任务使其在loop中执行。 2029 2030##### ffrt_loop_destroy 2031 2032声明 2033 2034```c 2035FFRT_C_API int ffrt_loop_destroy(ffrt_loop_t loop); 2036``` 2037 2038参数 2039 2040- `loop`:loop对象。 2041 2042返回值 2043 2044- 0表示成功,-1表示失败。 2045 2046描述 2047 2048- 销毁一个loop,同时和队列解除绑定。 2049 2050##### ffrt_loop_run 2051 2052声明 2053 2054```c 2055FFRT_C_API int ffrt_loop_run(ffrt_loop_t loop); 2056``` 2057 2058参数 2059 2060- `loop`:loop对象。 2061 2062返回值 2063 2064- 0表示成功,-1表示失败。 2065 2066描述 2067 2068- 启动一个loop,调用此方法的线程会同步执行loop,在loop中会执行队列的任务、监听poller事件触发、监听timer定时器触发。 2069 2070##### ffrt_loop_stop 2071 2072声明 2073 2074```c 2075FFRT_C_API void ffrt_loop_stop(ffrt_loop_t loop); 2076``` 2077 2078参数 2079 2080- `loop`:loop对象。 2081 2082描述 2083 2084- 停止一个loop,调用此方法使执行loop的线程退出循环。 2085 2086##### ffrt_loop_epoll_ctl 2087 2088声明 2089 2090```c 2091int ffrt_loop_epoll_ctl(ffrt_loop_t loop, int op, int fd, uint32_t events, void *data, ffrt_poller_cb cb) 2092``` 2093 2094参数 2095 2096- `loop`:loop对象。 2097- `op`:fd操作符,参考epoll_ctl的操作类型。 2098- `fd`:事件描述符。 2099- `events`:事件,参考epoll_ctl的事件类型。 2100- `data`:回调函数的入参。 2101- `cb`:回调函数。 2102 2103返回值 2104 2105- 0表示成功,-1表示失败。 2106 2107描述 2108 2109- 管理loop上的监听fd事件,事件的监听和回调执行在loop线程上处理。 2110 2111##### ffrt_loop_timer_start 2112 2113声明 2114 2115```c 2116FFRT_C_API ffrt_timer_t ffrt_loop_timer_start(ffrt_loop_t loop, uint64_t timeout, void* data, ffrt_timer_cb cb, bool repeat); 2117``` 2118 2119参数 2120 2121- `loop`:loop对象。 2122- `timeout`:定时器时间,单位是毫秒。 2123- `cb`:到期后的回调函数。 2124- `data`:回调函数的输入参数。 2125- `repeat`:是否循环定时器。 2126 2127返回值 2128 2129- `ffrt_timer_t`定时器句柄。 2130 2131描述 2132 2133- 在loop上启动一个定时器,用法和`ffrt_timer_start`一致,只是定时器的监听和回调执行在loop线程上处理。 2134 2135##### ffrt_loop_timer_stop 2136 2137声明 2138 2139```c 2140FFRT_C_API int ffrt_loop_timer_stop(ffrt_loop_t loop, ffrt_timer_t handle); 2141``` 2142 2143参数 2144 2145- `loop`:loop对象。 2146- `handle`:定时器句柄。 2147 2148返回值 2149 2150- 0表示成功,-1表示失败。 2151 2152描述 2153 2154- 取消一个定时器,用法和`ffrt_timer_stop`一致。 2155 2156#### 样例 2157 2158- 样例1:循环与并发队列: 2159 2160 ```c 2161 #include <pthread.h> 2162 #include <unistd.h> 2163 #include <stdio.h> 2164 #include "c/loop.h" 2165 2166 void* ThreadFunc(void* p) 2167 { 2168 int ret = ffrt_loop_run(p); 2169 if (ret == 0) { 2170 printf("loop normal operation."); 2171 } 2172 return nullptr; 2173 } 2174 2175 int main(int narg, char** argv) 2176 { 2177 // 创建并发队列 2178 ffrt_queue_attr_t queue_attr; 2179 (void)ffrt_queue_attr_init(&queue_attr); 2180 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr); 2181 2182 // 创建loop 2183 auto loop = ffrt_loop_create(queue_handle); 2184 2185 // 启动独立线程来执行loop 2186 pthread_t thread; 2187 pthread_create(&thread, 0, ThreadFunc, loop); 2188 2189 // 终止并销毁loop 2190 ffrt_loop_stop(loop); 2191 int ret = ffrt_loop_destroy(loop); 2192 2193 // 销毁并发队列 2194 ffrt_queue_attr_destroy(&queue_attr); 2195 ffrt_queue_destroy(queue_handle); 2196 return 0; 2197 } 2198 ``` 2199 2200- 样例2:循环、并发队列和定时器: 2201 2202 ```c 2203 #include <pthread.h> 2204 #include <unistd.h> 2205 #include <stdio.h> 2206 #include <functional> 2207 #include <sys/epoll.h> 2208 #include <sys/eventfd.h> 2209 #include "c/loop.h" 2210 #include "ffrt.h" 2211 2212 void* ThreadFunc(void* p) 2213 { 2214 int ret = ffrt_loop_run(p); 2215 return nullptr; 2216 } 2217 2218 static void test_fun(void* data) 2219 { 2220 *(int*)data += 1; 2221 } 2222 2223 static void (*cb)(void*) = test_fun; 2224 2225 void testCallBack(void *data, unsigned int events) {} 2226 2227 struct TestData { 2228 int fd; 2229 uint64_t expected; 2230 }; 2231 2232 int main(int narg, char** argv) 2233 { 2234 // 创建并发队列 2235 ffrt_queue_attr_t queue_attr; 2236 (void)ffrt_queue_attr_init(&queue_attr); 2237 ffrt_queue_t queue_handle = ffrt_queue_create(ffrt_queue_concurrent, "test_queue", &queue_attr); 2238 2239 // 创建loop 2240 auto loop = ffrt_loop_create(queue_handle); 2241 int result1 = 0; 2242 2243 // 向loop队列提交一个任务 2244 std::function<void()> &&basicFunc1 = [&result1]() {result1 += 10;}; 2245 ffrt_task_handle_t task1 = ffrt_queue_submit_h(queue_handle, ffrt::create_function_wrapper(basicFunc1, ffrt_function_kind_queue), nullptr); 2246 2247 // 启动独立线程来执行loop 2248 pthread_t thread; 2249 pthread_create(&thread, 0, ThreadFunc, loop); 2250 2251 static int x = 0; 2252 int* xf = &x; 2253 void* data = xf; 2254 uint64_t timeout1 = 20; 2255 uint64_t timeout2 = 10; 2256 uint64_t expected = 0xabacadae; 2257 2258 int testFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); 2259 struct TestData testData {.fd = testFd, .expected = expected}; 2260 2261 // 向loop注册一个定时器 2262 ffrt_timer_t timeHandle = ffrt_loop_timer_start(loop, timeout1, data, cb, false); 2263 2264 // 向loop注册一个fd监听 2265 int ret = ffrt_loop_epoll_ctl(loop, EPOLL_CTL_ADD, testFd, EPOLLIN, (void*)(&testData), testCallBack); 2266 if (ret == 0) { 2267 printf("ffrt_loop_epoll_ctl执行成功。\n"); 2268 } 2269 ssize_t n = write(testFd, &expected, sizeof(uint64_t)); 2270 usleep(25000); 2271 // 删除fd监听 2272 ffrt_loop_epoll_ctl(loop, EPOLL_CTL_DEL, testFd, 0, nullptr, nullptr); 2273 2274 // 终止loop 2275 ffrt_loop_stop(loop); 2276 pthread_join(thread, nullptr); 2277 2278 // 删除定时器 2279 ffrt_loop_timer_stop(loop, timeHandle); 2280 2281 // 销毁loop 2282 ret = ffrt_loop_destroy(loop); 2283 2284 // 销毁并发队列 2285 ffrt_queue_attr_destroy(&queue_attr); 2286 ffrt_queue_destroy(queue_handle); 2287 return 0; 2288 } 2289 ``` 2290