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