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