前言

线程是计算机中的一种执行单元,是操作系统进行调度的最小单位。它是进程中的实际运行单位,每个进程可以包含多个线程。线程可以理解为进程中的一个执行流,它独立运行,拥有独立的栈和寄存器,但共享进程的资源,如内存空间、文件等。线程通过并发执行,将一个进程的任务划分成多个子任务并行处理,以提高程序的性能和响应速度。

线程分为用户线程和内核线程。用户线程是由用户级线程库实现和调度的,操作系统并不直接支持用户线程,因此线程的创建、销毁、调度等都是由应用程序自己完成。内核线程则由操作系统内核管理,操作系统负责线程的创建、销毁和调度。内核线程相对于用户线程更加稳定和可靠,但创建和销毁线程的开销较大。

线程具有以下特点:

  1. 轻量级:线程创建和销毁的开销较小,所需的资源较少。
  2. 并发执行:多个线程可以同时执行,通过在不同的CPU核心上运行,充分利用多核处理器的性能。
  3. 共享资源:线程可以访问和共享进程的资源,如堆内存、全局变量、文件等。
  4. 通信简单:线程之间可以通过共享内存进行通信,也可以使用同步机制如互斥锁、信号量等进行协调和同步。
  5. 上下文切换:线程之间需要进行切换执行,由于线程的切换开销较小,因此可以快速响应和处理任务。

线程的使用可以有效地提高程序的性能和资源利用率,特别适用于多任务并发处理的场景,如网络服务器、图形界面应用、多媒体处理等。但线程编程也存在一些挑战和风险,如线程安全、共享资源竞争等问题,需要合理地设计和管理线程使用,以保证程序的正确性和稳定性。

一、线程模型

1.概述

HarmonyOS应用中,每个进程都有一个主线程,主线程具有以下职责:

  1. 执行UI绘制:主线程负责处理应用界面的绘制操作,包括布局、绘制和刷新等。

  2. 管理主线程的ArkTS引擎实例:主线程通过管理ArkTS引擎实例,使得多个UIAbility组件能够在主线程上运行,实现界面的展示和交互。

  3. 管理其他线程的ArkTS引擎实例:主线程还负责管理其他线程(例如Worker线程)的ArkTS引擎实例,包括启动和终止其他线程。

  4. 分发交互事件:主线程接收用户的交互事件,如点击、滑动等,并将这些事件分发给相应的UIAbility进行处理。

  5. 处理应用代码的回调:主线程负责处理应用代码的回调函数,包括事件处理和生命周期管理。例如,当用户触发某个事件时,主线程会调用相应的回调函数进行处理。

  6. 接收Worker线程发送的消息:主线程与Worker线程之间通过消息机制进行通信,主线程接收并处理Worker线程发送的消息。

除了主线程之外,还有一类与主线程并行的独立线程,称为Worker线程。Worker线程主要用于执行耗时操作,但不可以直接操作UI。Worker线程在主线程中创建,与主线程相互独立。一个进程最多可以创建8个Worker线程。

目前,HarmonyOS提供了两种线程间通信的方式,分别是Emitter和Worker。

  1. Emitter(发射器):Emitter主要适用于线程间的事件同步。它可以在不同的线程之间传递事件,并确保事件的顺序和同步性。通过Emitter,一个线程可以触发一个事件,然后其他线程可以监听并处理这个事件。这有助于不同线程之间的数据共享和协调。

  2. Worker(工作者):Worker主要用于新开一个线程执行耗时任务。当需要执行一些耗时操作时,为了不阻塞主任务的执行,可以使用Worker线程。Worker线程是在主线程的上下文中创建的独立线程,它可以执行一些耗时任务,如网络访问、文件读写等。工作线程可以与主线程并行执行,以提高应用的响应性和性能。

2.Emitter

2.1 订阅事件

import emitter from "@ohos.events.emitter";

// 定义一个eventId为1的事件
let event = {
eventId: 1
}; // 收到eventId为1的事件后执行该回调
let callback = (eventData) => {
console.info('event callback');
}; // 订阅eventId为1的事件
emitter.on(event, callback);

2.2 发送事件

import emitter from "@ohos.events.emitter";

// 定义一个eventId为1的事件,事件优先级为Low
let event = {
eventId: 1,
priority: emitter.EventPriority.LOW
}; let eventData = {
data: {
"content": "c",
"id": 1,
"isEmpty": false,
}
}; // 发送eventId为1的事件,事件内容为eventData
emitter.emit(event, eventData);

3.Worker

3.1 配置文件

以下配置文件都是在build-profile.json5中的

"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/workers/worker.ts"
]
}
}

3.2 创建文件

worker.ts文件

import worker from '@ohos.worker';

let parent = worker.workerPort;

// 处理来自主线程的消息
parent.onmessage = function(message) {
console.info("onmessage: " + message)
// 发送消息到主线程
parent.postMessage("message from worker thread.")
}

3.3 使用线程模型

import worker from '@ohos.worker';

let wk = new worker.ThreadWorker("entry/ets/workers/worker.ts");

// 发送消息到worker线程
wk.postMessage("message from main thread.") // 处理来自worker线程的消息
wk.onmessage = function(message) {
console.info("message from worker: " + message) // 根据业务按需停止worker线程
wk.terminate()
}

注意:build-profile.json5中配置的worker.ts的相对路径都为./src/main/ets/workers/worker.ts时,在Stage模型下创建worker需要传入路径entry/ets/workers/worker.ts;

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing,不定期分享原创知识。
  • 更多鸿蒙最新技术知识点,请关注作者博客:https://t.doruo.cn/14DjR1rEY

鸿蒙HarmonyOS实战-Stage模型(线程模型)的更多相关文章

  1. C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型

    原文:C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型 线程模型 SocketAsyncEventArgs编程模式不支持设置同时工作线程个数,使用的NET的IO ...

  2. Dubbo入门到精通学习笔记(十一):Dubbo服务启动依赖检查、Dubbo负载均衡策略、Dubbo线程模型(结合Linux线程数限制配置的实战分享)

    文章目录 Dubbo服务启动依赖检查 Dubbo负载均衡策略 Dubbo线程模型(结合Linux线程数限制配置的实战分享) 实战经验分享( ** 属用性能调优**): Dubbo服务启动依赖检查 Du ...

  3. Netty实战七之EventLoop和线程模型

    简单地说,线程模型指定了操作系统.编程语言.框架或者应用程序的上下文中的线程管理的关键方面.Netty的线程模型强大但又易用,并且和Netty的一贯宗旨一样,旨在简化你的应用程序代码,同时最大限度地提 ...

  4. Netty 基本组件与线程模型

    Netty 的学习内容主要是围绕 TCP 和 Java NIO 这两个点展开的,由于 Netty 是基于 Java NIO 的 API 之上构建的网络通讯框架,Java NIO 中的几个组件,都能在 ...

  5. [并发并行]_[线程模型]_[Pthread线程使用模型之一管道Pipeline]

    场景 1.经常在Windows, MacOSX 开发C多线程程序的时候, 经常需要和线程打交道, 如果开发人员的数量不多时, 同时掌握Win32和pthread线程 并不是容易的事情, 而且使用Win ...

  6. Netty In Action中文版 - 第十五章:选择正确的线程模型

    http://blog.csdn.net/abc_key/article/details/38419469 本章介绍 线程模型(thread-model) 事件循环(EventLoop) 并发(Con ...

  7. 深入Netty逻辑架构,从Reactor线程模型开始

    本文是Netty系列第6篇 上一篇文章我们从一个Netty的使用Demo,了解了用Netty构建一个Server服务端应用的基本方式.并且从这个Demo出发,简述了Netty的逻辑架构,并对Chann ...

  8. 看我是如何处理自定义线程模型---java

    看过我之前文章的园友可能知道我是做游戏开发,我的很多思路和出发点是按照游戏思路来处理的,所以和web的话可能会有冲突,不相符合. 来说说为啥我要自定义线程模型呢? 按照我做的mmorpg或者mmoar ...

  9. HBase的Write Ahead Log (WAL) —— 整体架构、线程模型

    解决的问题 HBase的Write Ahead Log (WAL)提供了一种高并发.持久化的日志保存与回放机制.每一个业务数据的写入操作(PUT / DELETE)执行前,都会记账在WAL中. 如果出 ...

  10. java线程内存模型,线程、工作内存、主内存

    转自:http://rainyear.iteye.com/blog/1734311 java线程内存模型 线程.工作内存.主内存三者之间的交互关系图: key edeas 所有线程共享主内存 每个线程 ...

随机推荐

  1. KL散度和交叉熵的对比介绍

    KL散度(Kullback-Leibler Divergence)和交叉熵(Cross Entropy)是在机器学习中广泛使用的概念.这两者都用于比较两个概率分布之间的相似性,但在一些方面,它们也有所 ...

  2. CentOS下修改 MySQL 的密码

    做服务器运维,修改 MySQL 的密码是经常的需要,定期修改 MySQL 密码是网站安全的一个保证.这里记录一下修改 MySQL 密码的一些命令,方便以后查看. 修改root密码 CentOS 下 M ...

  3. mm系列权重文件瘦身

    瘦身脚本: (会在resnet50.pth文件的同级目录下生成一个resnet50_thin.pth) import os import torch root_dir = os.getcwd() de ...

  4. 实训篇-Html-注册页面【简单】

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. 使用pycuda替换字符串,使用cuda替换字符串

    写一个python的cuda程序,实现字符串列表的字符串替换,把所有的123替换成xinyuuliu 以下是一个简单的 Python CUDA 代码示例,用于实现字符串列表的字符串替换.它使用了 NV ...

  6. 浏览器端实现类似input限制输入两位小数,输入时光标从输入位置移动到最后

    1.问题描述展示 示例代码所做限制为不允许输入字母d,其他限制规则可以根据需求自己调整,使用React编写,其他框架或原生均可根据该代码理解原理进行转变,特意使用了中文键盘可以看到输入框下面白色框闪出 ...

  7. js获取时间差,返回格式为01天02小时03秒

    // 获取时间差 返回值格式:01天02小时30秒 export function caclulateDiffTime(start, end): string { start = new Date(s ...

  8. 关于mac使用figma以及企业微信3.1.18版本,CPU系统占用率飙升至70%

    问题描述 使用一段时间正常,不知道是修改了什么设置,还是有什么软件冲突,导致cpu使用率极高 系统进程中有一个 kernel_task 占用了大量的cpu 并且该占用并不会消失,只要figma打开就会 ...

  9. 【笔记】报错:numeric or value error: character to number conversion error

    报错:numeric or value error: character to number conversion error 报错如下: 数据库操作错误."2327,13619/v1:65 ...

  10. 力扣12(java)-整数转罗马数字(中等)

    题目: 罗马数字包含以下七种字符:I, V, X, L, C, D, M 1 字符 数值 2 I 1 3 V 5 4 X 10 5 L 50 6 C 100 7 D 500 8 M 1000 例如, ...