diff --git a/OAT.xml b/OAT.xml index 6b94ea812aa1e444b6b52337bf0eec17d79dcc19..8b1ee7c6171ed83c2ce05e6858416eb902b9b986 100644 --- a/OAT.xml +++ b/OAT.xml @@ -169,6 +169,8 @@ Note:If the text contains special characters, please escape them according to th + + diff --git a/code/ArkTS1.2/ParallelSample/README.md b/code/ArkTS1.2/ParallelSample/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2a3440d21108134a64c04a755e6dd37b4ff30ce4 --- /dev/null +++ b/code/ArkTS1.2/ParallelSample/README.md @@ -0,0 +1,91 @@ +# 并行化处理 + +### 介绍 + +### EAWorker介绍 +EACoroutine特性是为开发者提供一个能够独占线程的协程,用于执行特定的任务。 +ArkTS演进的世界里只有协程的概念,用户创建的并发/异步任务实际通过不同的协程执行,当用户抛出重载任务会导致某个协程执行任务耗时过长影响系统调用,或用户期望有一个能够独立执行特定任务的协程,因此此处补充独占协程(Exclusive ArkTS Coroutine)。 + +### EAWorker工作机制 +EAWorker 中的任务均独立运行在各自的工作线程中。由于 ArkTS 1.2 采用内存天然共享机制,EAWorker 与主线程以及其他工作线程之间可通过内存变量进行通信(若涉及多线程共享变量,需使用锁进行保护,或采用线程安全容器)。 +在创建 EAWorker 时,可选择是否启用 interop 功能。不过,创建 EAWorker 会产生一定的内存和性能开销,而且大量创建 EAWorker 会抢占系统线程资源,因此需要对 EAWorker 的创建数量进行限制。 +若要创建 EAWorker,可调用 EAWorker 构造函数并传入一个布尔值参数,该参数用于控制是否启用 interop 功能,此功能仅在混合虚拟机环境下生效。 + +在混合虚拟机环境中,创建EAWorker,EAWorker对象可以调用run方法向EAWorker抛任务,利用EACoroutine设置并行化使用场景。 +创建打开interop的EAWorker对象,创建多个任务,用EAWorker对象并行地执行这些任务。观察结果是否和预期一致。 + +### AsyncLock(异步锁) + +为了解决多并发实例间的数据竞争问题,ArkTS语言基础库引入了异步锁能力。为了开发者的开发效率,AsyncLock对象支持跨并发实例引用传递。 + +使用异步锁的方法需要标记为async,调用方需要await修饰调用,才能保证时序正确。因此会导致外层调用函数全部标记成async。 + +### TaskPool介绍 +任务池(TaskPool)作用是为应用程序提供一个多线程的运行环境,降低整体资源的消耗、提高系统的整体性能,且无需关心线程实例的生命周期。 + +### TaskPool工作机制 +TaskPool 允许开发者在宿主线程中封装任务,并将其抛入任务队列。系统会自动挑选合适的工作线程,实现任务的分发与执行,最后将任务执行结果返回给宿主线程。 +该接口设计简洁,易于使用,支持对任务进行执行、取消操作,同时具备指定任务优先级的能力。此外,通过系统统一的线程管理机制,结合动态调度和负载均衡算法,能够有效节省系统资源。 +系统默认会启动一个任务工作线程。当任务数量增加时,工作线程会自动扩容,其数量上限与当前设备的物理核数相关,具体数量由系统内部管理,以确保实现最优的调度和执行效率。当长时间没有任务需要分发时,工作线程会自动缩容,从而减少工作线程的数量。 + +### 效果预览 + +效果如下所示: + +|EAWorker|taskPool| +|--------------------------------|--------------------------------| +|![Alt text](entry/src/main/resources/base/media/eaworker.PNG)|![Alt text](entry/src/main/resources/base/media/taskpool.PNG)| + +使用说明 + +1. 在EAworker界面,依次点击蓝色按钮会在对应下方预期结果部分打印出对应日志; +2. 在taskPool界面,依次点击蓝色按钮会在对应下方预期结果部分打印出对应日志; + + +### 工程目录 + +``` +entry/src/main/ets/ +|---pages +| |---index.ets // 并行化首页 +``` + +### 具体实现 + +* EAWorker 源码参考: [Index.ets](entry/src/main/ets/pages/Index.ets) + * 不同线程共同操作一个函数-加锁 在[Index.ets](entry/src/main/ets/pages/Index.ets)中创建EAWoker线程,调用foo(),并且foo()加锁; + * 不同线程共同操作一个函数-不加锁 在[Index.ets](entry/src/main/ets/pages/Index.ets)中创建EAWoker线程,调用fooUnlock(); + * 不同线程操作不同函数-加锁 在[Index.ets](entry/src/main/ets/pages/Index.ets)中创建EAWoker线程,调用fooTest() fooTest2() fooTest3(),并且fooTest() fooTest2() fooTest3() 函数都加锁; + * 不同线程操作不同函数-不加锁 在[Index.ets](entry/src/main/ets/pages/Index.ets)中创建EAWoker线程,调用fooTestUnlock() fooTestUnlock2() fooTestUnlock3(); + * 不同线程共享一个容器 在[Index.ets](entry/src/main/ets/pages/Index.ets)中创建EAWoker线程 map容器,调用fooMapTest() fooMapTest2(); + * 不同线程操作一个文件 在[Index.ets](entry/src/main/ets/pages/Index.ets)中创建EAWoker线程,主线程调用createFileTest() 子线程调用readFile(); +* taskPool 源码参考: [Index.ets](entry/src/main/ets/pages/Index.ets) + * 执行一组有关联的任务 在[Index.ets](entry/src/main/ets/pages/Index.ets)中调用taskTest()函数创建一组TaskPoll线程; + * 任务优先级 在[Index.ets](entry/src/main/ets/pages/Index.ets)中 调用concurrentFunc()函数循环创建TaskPoll线程; + * 并发函数计算两数之和 在[Index.ets](entry/src/main/ets/pages/Index.ets)中 调用concurrentFuncAdd()函数创建TaskPoll线程计算两数之和; + +### 相关权限 + +无 + +### 依赖 + +无 + +### 约束与限制 + +1. 本示例仅支持标准系统上运行,支持设备:Phone; +2. 本示例为Stage模型,支持API20版本SDK,SDK版本号(API Version 20),镜像版本号(5.0.1.57)。 +3. 本示例需要使用DevEco Studio 版本号(6.0.0.6)版本才可编译运行。 + +### 下载 + +如需单独下载本工程,执行如下命令: + +``` +git init +git config core.sparsecheckout true +echo code/ArkTS1.2/ParallelSample/ > .git/info/sparse-checkout +git remote add origin https://gitee.com/openharmony/applications_app_samples.git +git pull --rebase origin master +``` \ No newline at end of file diff --git a/code/ArkTS1.2/ParallelSample/entry/src/main/resources/base/media/eaworker.PNG b/code/ArkTS1.2/ParallelSample/entry/src/main/resources/base/media/eaworker.PNG new file mode 100644 index 0000000000000000000000000000000000000000..d31de1b819449588d5044742b503f2754519ebe4 Binary files /dev/null and b/code/ArkTS1.2/ParallelSample/entry/src/main/resources/base/media/eaworker.PNG differ diff --git a/code/ArkTS1.2/ParallelSample/entry/src/main/resources/base/media/taskpool.PNG b/code/ArkTS1.2/ParallelSample/entry/src/main/resources/base/media/taskpool.PNG new file mode 100644 index 0000000000000000000000000000000000000000..bfb24abba16948f1f666ba70e7c5834b4d8f94bd Binary files /dev/null and b/code/ArkTS1.2/ParallelSample/entry/src/main/resources/base/media/taskpool.PNG differ diff --git a/code/ArkTS1.2/ParallelSample/ohosTest.md b/code/ArkTS1.2/ParallelSample/ohosTest.md new file mode 100644 index 0000000000000000000000000000000000000000..6be35558d35444ae35fad77d2bd77d82597b2208 --- /dev/null +++ b/code/ArkTS1.2/ParallelSample/ohosTest.md @@ -0,0 +1,15 @@ +# 并行化使用示例测试用例 + +## 用例表 + +| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 | +|-----------------------------------|-------------------------------------|----------------------|------------------------------------|------|------| +| EAWorker-不同线程共同操作一个函数-加锁 | 1. 需在真机测试
2. 构建并安装测试hap | 点击【EAWorker-不同线程共同操作一个函数-加锁】按钮 | 打印日志参考如下:(不会出现交替打印)
*************************@@@@@@@@@@@@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&&&&&& | 否 | Pass | +| EAWorker-不同线程共同操作一个函数-不加锁 | 1. 需在真机测试
2. 构建并安装测试hap | 点击【EAWorker-不同线程共同操作一个函数-不加锁】按钮 | 打印日志参考如下:(可能会出现交替打印)
&&&&&&&&&&&&&&&&&&&&&&&*&*&&&&&&&&*****************************************@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | 否 | Pass | +| EAWorker-不同线程操作不同函数-加锁 | 1. 需在真机测试
2. 构建并安装测试hap | 点击【EAWorker-不同线程操作不同函数-加锁】按钮 | 打印日志参考如下:
111111111111111111111111133333333333333333333333332222222222222222222222222 | 否 | Pass | +| EAWorker-不同线程操作不同函数-不加锁 | 1. 需在真机测试
2. 构建并安装测试hap | 点击【EAWorker-不同线程操作不同函数-加锁】按钮 | 打印日志参考如下:
1111111111111111131333133333333333323222222222222222222222 | 否 | Pass | +| EAWorker-不同线程共享一个容器 | 1. 需在真机测试
2. 构建并安装测试hap | 点击【EAWorker-不同线程共享一个容器】按钮 | 显示计算结果:
50或100 | 否 | Pass | +| EAWorker-不同线程读写同一个文件 | 1. 需在真机测试
2. 构建并安装测试hap | 点击【EAWorker-不同线程读写同一个文件】按钮 | 打印日志如下:
com.samples.EAWorker successfully launched | 否 | Pass | +| taskPool-执行一组有关联的任务 | 1. 需在真机测试
2. 构建并安装测试hap | 点击【taskPool-执行一组有关联的任务】按钮 | 打印日志如下:
[100,200,300][10,20,30] | 否 | Pass | +| taskPool-任务优先级 | 1. 需在真机测试
2. 构建并安装测试hap | 点击【taskPool-任务优先级】按钮 | 打印日志如下:
高中高高高高高中高高高高中中中低中中中中中低低低低低低低低低 | 否 | Pass | +| taskPool-计算两数之和 | 1. 需在真机测试
2. 构建并安装测试hap | 点击【taskPool-计算两数之和】按钮 | 打印日志如下:
12 | 否 | Pass | \ No newline at end of file