HarmonyOS 鸿蒙Next ArkTs线程API threadpool和worker均基于Actor模型实现,如何解决多线程通信时消息实时性问题
HarmonyOS 鸿蒙Next ArkTs线程API threadpool和worker均基于Actor模型实现,如何解决多线程通信时消息实时性问题
我们的业务场景中,有一类任务属于计算密集型任务,因此我们需要发起一个线程,不断地将各类数据送入线程,线程中将依赖各类数据的时间戳,对数据进行时序上的对齐,之后对齐后的数据会参与一次计算,计算频率为10~30HZ,计算结果将用于动画渲染。因此这个线程的输入数据和输出数据之间存在实时性要求,输出数据与输入数据时间差不应超过30ms,否则动画渲染将会有一定的延迟。
我们的业务场景可以描述为下图:
我们已经尝试使用鸿蒙Next提供的线程API threadpool和worker分别实现,分别遇到不同的问题
使用threadpool实现,线程计算时长存在限制,计算超过3分钟,线程被系统主动终止,无法满足长时间运行需求
使用worker实现,worker只有单个消息队列,多条数据流通过postMessage发送到worker时,出现消息积压,消息从发送到接收延迟长达数秒,消息的实时性丧失导致无法使用
延迟统计方法如下:
宿主线程创建ARMessage时,记录系统时间戳,消息创建后立即发送
Worker线程收到消息时,计算系统时间差
// 发送消息,记录系统时间差
public UpdateAdasPerceptionCogTree(cogTree: AdasPerceptionCogTree): void {
if (!cogTree || !cogTree.roads) {
return
}
let msg = new AdsCogTreeMsg(cogTree)
this.arWorker.postMessage(msg)
}
// worker内接收消息后,立即打印与创建时的时间戳差值
function processUpdateAdasPerceptionCogTreeMsg(msg: ArMessage) {
let cogTree = (msg as AdsCogTreeMsg).value
hilog.debug(0, “AdsCogDelay”, “,” + (systemDateTime.getUptime(systemDateTime.TimeType.STARTUP) - msg.sysTs))
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
日志打印结果如下,延迟逐渐增加至6~7秒
10-11 10:25:38.115 AdsCogDelay D ,0
10-11 10:25:38.753 AdsCogDelay D ,21
10-11 10:25:39.317 AdsCogDelay D ,0
10-11 10:25:39.960 AdsCogDelay D ,57
10-11 10:25:40.547 AdsCogDelay D ,2
10-11 10:25:41.115 AdsCogDelay D ,20
10-11 10:25:41.776 AdsCogDelay D ,165
10-11 10:25:42.438 AdsCogDelay D ,243
10-11 10:25:42.888 AdsCogDelay D ,59
10-11 10:25:51.347 AdsCogDelay D ,7627
10-11 10:25:51.871 AdsCogDelay D ,7251
10-11 10:25:52.404 AdsCogDelay D ,7022
10-11 10:25:52.924 AdsCogDelay D ,6891
10-11 10:25:53.444 AdsCogDelay D ,6684
10-11 10:25:53.927 AdsCogDelay D ,6461
10-11 10:25:54.383 AdsCogDelay D ,6339
10-11 10:25:54.902 AdsCogDelay D ,6141
10-11 10:25:55.316 AdsCogDelay D ,5755
10-11 10:25:55.824 AdsCogDelay D ,5577
10-11 10:25:56.294 AdsCogDelay D ,5217
10-11 10:25:56.731 AdsCogDelay D ,4892
10-11 10:25:57.226 AdsCogDelay D ,4890
10-11 10:25:57.668 AdsCogDelay D ,4722
10-11 10:25:58.157 AdsCogDelay D ,4544
10-11 10:25:58.558 AdsCogDelay D ,4279
10-11 10:25:59.067 AdsCogDelay D ,3887
10-11 10:25:59.560 AdsCogDelay D ,3608
10-11 10:26:00.035 AdsCogDelay D ,3381
我们尝试过使用API 12,将消息封装成Sendable class,并使用ThreadWorker.postMessageWithSharedSendable()
接口发送消息。按照文档的说法,Sendable class对象发送时不会发生序列化,而会发生引用的所有权转移。但事实是,消息的延迟并没有改善
之前在Android平台,我们基于共享内存的方式实现两个线程之间的消息通信,HarmonyNext似乎没有在ArkTs中提供共享内存的线程API
题目中出现消息阻塞的主要原因是CogTree消息较长,消息处理逻辑耗时过长,每帧耗时500ms左右,worker内只能以2HZ响应,而发送端以3HZ发送,导致消息积压
综上,应保证消费端处理消息的速度>=生产速度,才能避免消息阻塞带来的延迟
HarmonyOS 鸿蒙Next ArkTs线程API中的threadpool和worker均基于Actor模型实现,这一设计旨在提高多线程任务的执行效率和系统的整体性能。针对多线程通信时消息实时性问题,可以采取以下措施来解决:
- 优化线程池配置:根据任务的特性和执行时间,合理配置线程池的大小和线程优先级,确保任务能够及时得到处理。
- 使用高效通信机制:采用共享内存、消息队列等高效通信机制,减少线程间的通信延迟。
- 避免资源竞争:合理设计数据结构,避免多线程同时访问同一资源导致的竞争和锁等待问题。
- 监控和调优:通过监控线程池的运行状态和任务执行情况,及时发现并解决潜在的性能瓶颈。
此外,开发者还可以利用HarmonyOS提供的性能调优工具和文档,对多线程应用进行更深入的分析和优化。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。