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