diff --git a/code/ArkTS1.2/ParallelSample/Readme.md b/code/ArkTS1.2/ParallelSample/Readme.md new file mode 100644 index 0000000000000000000000000000000000000000..233f5900430a3f5aaf57e5f10fe3884f2b073474 --- /dev/null +++ b/code/ArkTS1.2/ParallelSample/Readme.md @@ -0,0 +1,79 @@ +# 并行化处理 + +### 介绍 + +### EAWorker介绍 +EACoroutine特性是为开发者提供一个能够独占线程的协程,用于执行特定的任务。 +ArkTS演进的世界里只有协程的概念,用户创建的并发/异步任务实际通过不同的协程执行,当用户抛出重载任务会导致某个协程执行任务耗时过长影响系统调用,或用户期望有一个能够独立执行特定任务的协程,因此此处补充独占协程(Exclusive ArkTS Coroutine)。 + +### EAWorker工作机制 +EAWorker中的任务都独立的运行在自身的工程线程中,由于ArkTS1.2内存天然共享,因此EAWorker和主线程以及其他工作线程可以通过内存变量进行相互通信(多线程共享变量需使用锁保护,或者使用线程安全容器)。EAWorker在创建时可以选是否支持interop,并且在创建时会有一定内存和性能开销,大量创建EAWorker也会抢占系统线程资源,因此需要限制创建EAWorker的数量。 + +可以调用EAWorker构造函数,传入布尔值参数,该布尔值参数用于控制是否支持interop,此布尔值在混合虚拟机下生效。 + +在混合虚拟机环境中,创建EAWorker,EAWorker对象可以调用run方法向EAWorker抛任务,利用EACoroutine设置并行化使用场景。 +创建打开interop的EAWorker对象,创建多个任务,用EAWorker对象并行地执行这些任务。观察结果是否和预期一致. + +### AsyncLock(异步锁) + +为了解决多并发实例间的数据竞争问题,ArkTS语言基础库引入了异步锁能力。为了开发者的开发效率,AsyncLock对象支持跨并发实例引用传递。 + +由于ArkTS语言支持异步操作,阻塞锁容易产生死锁问题,因此我们在ArkTS中仅支持异步锁(非阻塞式锁)。 + +使用异步锁的方法需要标记为async,调用方需要await修饰调用,才能保证时序正确。因此会导致外层调用函数全部标记成async。 + +### TaskPool介绍 +任务池(TaskPool)作用是为应用程序提供一个多线程的运行环境,降低整体资源的消耗、提高系统的整体性能,且无需关心线程实例的生命周期。 + +### TaskPool工作机制 +TaskPool支持开发者在宿主线程封装任务抛给任务队列,系统选择合适的工作线程,进行任务的分发及执行,再将结果返回给宿主线程。接口直观易用,支持任务的执行、取消,以及指定优先级的能力,同时通过系统统一线程管理,结合动态调度及负载均衡算法,可以节约系统资源。系统默认会启动一个任务工作线程,当任务较多时会扩容,工作线程数量上限跟当前设备的物理核数相关,具体数量内部管理,保证最优的调度及执行效率,长时间没有任务分发时会缩容,减少工作线程数量。 + +### 效果预览 + +效果如下所示: + +|EAWorker|taskPool| +|--------------------------------|--------------------------------| +|![Alt text](https://gitee.com/openharmony/applications_app_samples/raw/1ede87921d00b0f6ab96ec2c00efcaa0bb1675c9/code/ArkTS1.2/ParallelSample/entry/src/main/resources/base/media/eaworker.PNG)|![Alt text](https://gitee.com/openharmony/applications_app_samples/raw/1ede87921d00b0f6ab96ec2c00efcaa0bb1675c9/code/ArkTS1.2/ParallelSample/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)版本才可编译运行。 \ 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