Processes and Threads

当一个应用的组件启动但是应用没有启动任何其他的组件运行,android就会启动一个新的Linux进程为一个应用开启一个单独的执行线程。默认的同一应用中的所有组件都是运行在同一个进程和主线程中。如果一个应用组件启动并且当这个进程已经存在(因为另外的这个应用的组件已经存在),然后这个组件启动在这个应用的进程中并使用同一个线程执行。但是你可以安排不同的组件在不同的进程中,也可以创建额外的线程在任何进程中。这里讨论怎么样进程和线程工作。

进程

默认的应用中所有的组件都是运行在同一个进程中,大多数应用不能改变这个,但是假如你需要控制哪些组件属于哪些进程,你可以在清单文件中控制。
清单文件的条目中各个组件都支持一个android:process属性这个可以修改组件在应用中的某个进程。你可以设置属性是每个组件都有自己的进程或不分享。你可以设置android:process是不同的应用组件在同一个进程之中,提供这个应用分享的同一个linux用户id和被同一个证书签名。

<application>标签也支持一个andorid:process属性,去设置默认的所有应用组件。
android也许决定关闭一个进程在某个时候,当内存低的时候或者其他的进程更直接的服务用户。应用组件运行在一个进程中会经常被销毁。当需要工作的时候,一个进程被重启的启动工作。
当决定进程被销毁后,android系统会权衡那个比较相对重要对用户。比如,他更容易关闭托管的activity。这个决定是否关闭进程,因此,取决于组件的运行状态。这个关闭的规则在下面讨论。

进程的生命周期

android系统会试着坚持尽可能长,但是最终需要移除老的进程来释放内容为新的应用或更重要的进程。觉得那个进程留下哪个被销毁,系统会放置很重要的层次里基于运行中的组件的状态。进程低重要程度的被淘汰,然后下一个不太重要的等等,这样是回收资源必须的。
1.前端进程:
一个用户操作的进程,这个进程被认为是前端的符合以下条件:
*一个activity用户正在交互(在调用onResume方法后)
*service绑定在一个用户的交互的activity上
*service正在前端运行,服务调用了startForeground().
*service正在执行一个生命周期(onCreate,onStart,onDestroy)
*broadcaseReceiver执行onReceive方法。
一般只有一个或几个前端的工作。被销毁只能作为最后的手段,假如内存低到他们不能继续运行。一般设备已经达到了内存分页的状态,以至于去杀掉前端的进程保持用户界面的响应。
2.可见进程
一个进程没有任何的前端操作组件,但是仍然影响用户看到的。一个进程可以被认为是可见的。
*一个activity不是在前端组件,但是他仍然可见,当这个时候,举个例子假如前端开启一个dialog,activity就会在背后。
*一个service绑定在一个可见的activity。
一个可见的进程可以认为非常的重要并且不会被销毁保证全部前端进程正在运行时。
3.服务进程
一个进程是一个服务被startServie方法启动并且不再两个更高的类。虽然服务进程不是直接的被用户看到,他们会做一些事用户会感觉的到(比如播放音乐或者从网络中下载数据),所以系统需要保持运行除非他们没有足够的内存当前端和可见的进程。
4.后台进程
一个进程只有一个activity当前不可见(onStop方法之后),这些进程不会影响用户的体验。通常这些许多后台进程运行,他们会保持一个LRU队列来确定一个activity最少最近的时候被销毁。假如一个activity实现了生命周期方法保存当前的状态杀掉进程后不会影响用户体验,因为当用户返回activity时activity已经存储了可见的状态。
5.空进程
一个进程不激活任何一个应用组件,这个唯一的理由是保存这个进程活着为了缓存目的,提高下次启动时间。这个时候系统会销毁这些进程为平衡这个系统的资源在进程缓和内存缓存。

android区分进程的最高等级,是基于当前活动的组件激活组件的活跃程度。比如一个进程持有一个服务和一个可见activity,这个进程的等级就是可见进程,不是服务进程。

另外,一个进程的等级会因为另外的进程需要依赖它而增加,一个进程可以服务另外一个排名低于他的进程。比如一个通信录提供进程A中服务一个进程B,或者这个服务在进程A被限制在一个组件的进程中,进程A至少比进程B更重要。
因为一个进程可以运行一个服务高于一个后台进程,一个activity初始很长时间开始一个服务操作,比如一个简单的创建一个线程,特别是一些创建简单的工作线程。比如一个activity上传一个图片到web站你会启动一个服务执行上传所有上传可以继续在后台当即使用户离开activity。使用服务可以保证至少是一个服务进程,不管activity发生什么。这一原因broadcastReceiver应该使用一个service而不是简单的使用线程操作。

线程

当一个应用启动后,系统会创建一个主线程。这个线程十分的重要因为它分发所有的事件给合适的用户界面包括绘画事件。这个线程在应用中和组件交互。所以这个主线程被称为UI线程。
系统不会单独的创建一个线程为单个组件。所有的组件都是运行在同一个被初始化的进程UI线程中,并且系统会调用每个组件的分发从线程中。所以,这个方法回应系统回调(比如onKeyDown())会回复应用的动作或者生命周期的回调函数都在进程的UI线程中。
举个例子,当用户点击一个按钮再屏幕上,你的应用UI线程会发送一个点击的事件给组件,反过来设置按下的状态并发送一个无效的请求在事件队列中。这个ui线程会分发请求并通知组件刷新自己。
当你的应用执行密集型工作在响应用户交互,这个单线程可能会导致执行效率低除非你实现你的应用很适当。特别是假如每个事件发生在UI线程中,执行很长时间的操作像网络访问,数据库查询会阻塞这个UI。当线程被阻塞,没有时间可以被分发,包括绘制事件。从用户的角度看,这个应用看上去会挂。更糟的是假如U线程被阻塞5秒钟就会提示用户ANR对话框。用户会很不高兴并且卸载它。

再者android的UI线程不是线程安全的。所以你不能控制UI在另外一个工作线程中,你必须所有的操作都在你的UI线程中控制。因此有两个规则:
1.不能阻塞线程
2.不能通过andorid UI toolkit从外部访问UI 线程。

工作线程

因为是单线程模式,这个很重要对于你的应用的UI,你不能阻塞UI线程。假如你的操作执行不是在瞬间,你应该明确你做的这些在一个独立的线程里。

比如下面的一个代码一个点击下载图片从一个线程展现ImageView。首先这个看上去很工作很正确,因为他创建的一个新的线程去执行网络操作,但是他违反了单个线程模式的第二个规则:不能通过android UI toolkit访问外部UI线程。这个简单修改在工作线程中代替你UI线程。这个会导致意想不到的行为,很难很耗时追踪。
为了修复这个问题,andorid提供了UI线程从其他线程进程访问。这里例句了方法:

1.      Activity.runOnUiThread(Runable);

2.      View.post(Runable)

3.      View.post(Runable,long)

比如,你可能需要使用View.post(Runable)方法。
现在实现一个线程安全:网络的操作在一个独立的线程里做当ImageView被操作在UI的线程里。

但是随着操作的复杂,这种代码复杂难维护。为了操作更复杂的交互和线程工作,你而已考虑使用Handler在工作的线程中,在过程中发送消息给UI线程。也许最好解决的方法是继承AsyncTask类,这个简单的执行一个工作线程任务可以和 UI交互。

使用AsyncTask

asyncTask允许执行异步的工作在你的界面中。这个执行不会阻塞操作在工作线程中并且发布结果到UI进程,不需要你处理线程和handler。
使用这个你必须继承asyncTask并实现一个doInbackground回调方法,这个是运行在一个后台的线程池中。更新你的UI,你应该在onpostexcute方法里,这个传递一个标记从ddoinBackground并运行在UI的主线程中,所以你可以线程安全更新你的UI。你可以运行这个任务使用execute在UI线程中。
现在UI是安全的并且代码也更简单,因为分离工作和一个UI工作部分。
你应该阅读asyncTask引用为一个全面理解怎么样使用这个类,但是这里快速的概括一下怎么样工作的。
1.你可以指定参数类型,进度值,最后的task值,用的范型。
2.方法doinBackground自动执行一个线程工作。
3.onPreExecute(),onPostExecute(),和onProgressUpdate被UI线程调用。
4.返回值被doinBackground发送给onPostExecute().
5.你可以调用publishProgress()在任何时候再doinBackground执行onProgressUpdate在UI线程中。
6.你可以取消任务在任何时候,从任何的线程中。
注意:
另外一个问题是你也许会遭遇当使用一个工作线程因为意想不到的事重启你的activity,比如运行时配置(像用户旋转屏幕),这个可能会销毁你的工作线程。想看看你怎么保持任务重启的时候怎么取消一个任务当activity被销毁,看源码shelves应用。

线程安全的方法

这些问题,你这个方法你使用的可以被调用超过一个线程,因此你必须写一个线程安全。
这个最适合用的方法用远程的像bound service。当你调用一个方法实现一个IBinder源在同一个进程中IBinder运行,这个方法被执行在一个线程中从线程池中这个系统支持一个同一个进程IBinder(它不执行在UI线程)。比如,服务的onBind()方法被调用在UI线程的进程中,这个方法返回一个对象onBind返回(比如,一个子类实现RPC方法)可以调用在其他的线程在线程池中。因为一个服务可以有多个客户,多个线程池应答同一个IBinder方法在同一个时间。IBinder方法必须,因此这个方法的实现是线程安全的。
相同的,一个内容提供者可以接收数据的请求来自其他的进程。虽然,Content Resolver和Content Provider类隐藏了进程间如何管理,ContentProvder方法回应一个请求的方法是query(),insert(),delete(),update(),和getType()这些都可以调用从一个线程在内容提供者的线程中。因为这些方法可以被无数个线程同时调用在同一时间,他们也必须实现线程安全。

进程间通信

android提供了一个机制用于进程间通信远程的请求,在一个方法被一个activity或另一个组件调用,但是远程执行(在另个进程中),和任何返回的结果调用者。这个需要分解方法调用和数据操作系统可以理解的水平,传送他从本地进程到远程的进程地址空间,然后重新装配重新定制。返回的值传递到返回的方向。返回的值传递到相反的方向。android提供了所有执行IPC事务,所以你可以聚焦在定义的实现RPC程序接口。

【从高压输电线的架空地线中汲取电能】一个25千瓦受控电源从735千伏线路的架空地线中汲取电能的SimPowerSystems模型(Simulink仿真实现)内容概要:本文介绍了一个基于SimPowerSystems的Simulink仿真模型,用于模拟从735千伏高压输电线的架空地线中汲取25千瓦电能的受控电源系统。该模型聚焦于高压输电线路中架空地线的能量回收技术,通过仿真手段实现对电能采集过程的建模与控制策略验证,体现了电力系统中新型能源获取方式的技术可行性与工程应用潜力。文中还提及该资源属于一系列电力系统仿真研究的一部分,涵盖微电网、储能优化、碳流追踪、鲁棒调度等多个前沿方向,配套提供Matlab/Simulink代码及网盘资料链接,便于科研人员复现与拓展研究。; 适合人群:具备电力系统基础知识、熟悉Matlab/Simulink仿真环境,从事电力工程、能源回收或智能电网相关研究的科研人员及研究生;有一定编程与建模仿真经验的高年级本科生或工程技术人员。; 使用场景及目标:①研究高压输电线路中架空地线的能量回收机制与建模方法;②掌握基于Simulink的电力系统仿真技术,特别是受控电源与电网交互的动态特性分析;③为开展能源 harvesting、分布式供能、电力电子变换器控制等相关课题提供参考模型与技术支撑; 阅读建议:建议结合提供的仿真模型文件进行实操演练,重点理解系统结构设计、参数设置与控制逻辑实现;同时可延伸学习文档中提到的其他电力系统优化与仿真案例,以拓宽研究视野和技术积累。
<think>我们正在分析OpenHarmony的hidumper工具,用户询问使用哪个命令可以获取内核空间和用户空间host进程信息。 根据帮助信息(-h选项的输出)和我们对hidumper功能的理解: 1. 帮助信息中列出了多个选项,其中与进程相关的选项是 `-p`。 2. `-p` 选项的描述是:processes information, include list and information of processes and threads. 3. 同时,`-p [pid]` 可以指定进程ID,dump该进程下的线程信息,包括smap, block channel, execute time, mountinfo等。 但是,用户需要的是“内核空间和用户空间host进程信息”。这里需要注意: - 在OpenHarmony中,用户空间的host服务(如hidumper_host)通常以进程形式运行。 - 内核空间的信息通常通过内核接口获取,而hidumper工具通过HDF驱动与内核交互。 根据帮助信息,直接获取进程信息的命令是 `-p`,它会列出所有进程(包括用户空间的host进程)。但是,内核空间的信息(如内核线程)通常也包含在进程列表中(内核线程的pid通常为负数或特殊标记,具体取决于实现)。 然而,在帮助信息中,并没有直接区分用户空间和内核空间的选项。但我们可以通过以下方式: - 使用 `-p` 列出所有进程,然后根据进程名或属性来区分用户空间和内核空间的进程(内核线程通常以方括号[]括起来,如[kthreadd])。 - 另外,帮助信息中还有 `--mem` 和 `--mem-smaps` 等选项可以查看内存信息,但用户需要的是进程信息。 因此,获取所有进程(包括用户空间进程和内核线程)的命令是: hidumper -p 如果要获取特定进程(比如用户空间的host服务进程)的详细信息,可以先通过 `hidumper -p` 找到进程ID,然后使用: hidumper -p [pid] 但是,用户可能希望一次性获取所有host服务(用户空间)和内核线程(内核空间)的信息。由于帮助信息中没有直接提供同时过滤这两类进程的选项,我们可以这样操作: 1. 使用 `hidumper -p` 获取所有进程列表。 2. 在输出中,用户空间的host服务进程通常有可识别的名字(如hidumper_host),而内核线程通常有特殊标记(如方括号[])。 所以,直接回答用户问题:使用 `hidumper -p` 命令可以获取所有进程信息,包括用户空间和内核空间的进程(线程)信息。然后通过解析输出,可以区分出用户空间的host进程和内核线程。 另外,如果用户只想查看host服务进程(用户空间),可以使用 `hidumper -p` 然后通过grep过滤进程名,例如: hidumper -p | grep 'hidumper_host' 但是,由于内核线程信息也包含在 `-p` 的输出中,所以该命令可以满足需求。 注意:帮助信息中还有一个 `-s` 选项用于列出系统能力(system abilities),但系统能力并不等同于进程信息。 因此,我们推荐使用 `hidumper -p` 来获取进程信息。 根据规则,在回答后需要提出3-5个相关问题。 注意:用户的问题是关于“使用哪个命令”,我们已经给出了答案:`hidumper -p`。 下面输出回答和问题。</think>在OpenHarmony中,使用`hidumper`工具获取内核空间和用户空间host进程信息的命令是: **`hidumper -p`** ### 详细说明: 1. **命令功能**: ```bash hidumper -p # 查看所有进程信息(包括内核空间和用户空间) ``` - 输出包含: - 用户空间host服务进程(如`hidumper_host`) - 内核线程(如`kworker`/`ksoftirqd`) - 关键系统进程(如`foundation`/`appspawn`) 2. **进阶用法**: ```bash hidumper -p [pid] # 查看指定进程的详细信息 ``` - 示例获取`hidumper_host`进程信息: ```bash # 先查找进程ID ps -ef | grep hidumper_host # 再通过ID查看详情(假设pid=1234) hidumper -p 1234 ``` - 输出内容: - 线程列表 - 内存映射(smap) - 挂载点信息(mountinfo) - CPU执行时间 3. **组合命令获取host服务**: ```bash # 1. 列出所有系统能力(含host服务) hidumper -ls # 2. 通过服务ID查看具体host进程 hidumper -s [服务ID] -a '-p' # 例如:hidumper -s 0x123456 -a '-p' ``` ### 输出示例片段: ``` Process list (PID/Name/State): -------------------------------- -1 [kthreadd] Running # 内核线程 1023 foundation Sleeping # 用户空间核心服务 1056 hidumper_host Running # host服务进程 ... ``` > ⚠️ 注意: > - 内核线程的PID通常为**负数**(如`-1`) > - 需要`root`权限才能查看完整进程信息 > - 使用`hidumper -p | grep -E "host|kthread"`可快速过滤目标进程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值