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