您的位置:首页 > 移动开发 > Android开发

Android进程与线程

2016-02-27 22:45 411 查看
Android的进程回收,最重要的是考量内存开销,以及电量等其他资源状况,此外每个进程承载的组件数量、单个应用开辟的进程数量等数量指标,也是作为衡量的一个重要标识。另外,一些运行时的时间开销,也被严格监控,启动慢的进程会很被强行kill掉。Android会定时检查上述参数,也会在一些很可能发生进程回收的时间点,比如某个组件执行完成后,来做回收的尝试。

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

进程和线程的关系:

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。

(3)处理机分给线程,即真正在处理机上运行的是线程。

(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

进程与线程的区别:

(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位

(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行

(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.

(4) 系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。但是进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于所有的线程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些

结论:

(1)线程是进程的一部分

(2)CPU调度的是线程

(3)系统为进程分配资源,不对线程分配资源

对比维度
多进程
多线程
总结
数据共享、同步
数据共享复杂,需要用IPC;数据是分开的,同步简单
因为共享进程数据,数据共享简单,但也是因为这个原因导致同步复杂
各有优势
内存、CPU
占用内存多,切换复杂,CPU利用率低
占用内存少,切换简单,CPU利用率高
线程占优
创建销毁、切换
创建销毁、切换复杂,速度慢
创建销毁、切换简单,速度很快
线程占优
编程、调试
编程简单,调试简单
编程复杂,调试复杂
进程占优
可靠性
进程间不会互相影响
一个线程挂掉将导致整个进程挂掉
进程占优
分布式
适应于多核、多机分布式;如果一台机器不够,扩展到多台机器比较简单
适应于多核分布式
进程占优
“消息收发”和“消息处理”可以分进程设计,“消息解码”、“业务处理”可以分线程设计。

进程是程序执行时的一个实例,即它是程序已经执行到课中程度的数据结构的汇集。从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。

线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。一个进程由几个线程组成(拥有很多相对独立的执行流的用户程序共享应用程序的大部分数据结构),线程与同属一个进程的其他的线程共享进程所拥有的全部资源。
进程有独立的地址空间,线程没有单独的地址空间(同一进程内的线程共享进程的地址空间)。

(下面的内容摘自Linux下的多线程编程

使用多线程的理由之一是和进程相比,它是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。

使用多线程的理由之二是线程间方便的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。

在Unix上编程采用多线程还是多进程的争执由来已久,这种争执最常见到在B/S通讯中服务端并发技术 的选型上,比如WEB服务器技术中,Apache是采用多进程的(perfork模式,每客户连接对应一个进程,每进程中只存在唯一一个执行线 程),Java的Web容器Tomcat、Websphere等都是多线程的(每客户连接对应一个线程,所有线程都在一个进程中)。

从Unix发展历史看,伴随着Unix的诞生多进程就出现了,而多线程很晚才被系统支持,例如Linux直到内核2.6,才支持符合Posix规范的NPTL线程库。进程和线程的特点,也就是各自的优缺点如下:

进程优点:编程、调试简单,可靠性较高。

进程缺点:创建、销毁、切换速度慢,内存、资源占用大。

线程优点:创建、销毁、切换速度快,内存、资源占用小。

线程缺点:编程、调试复杂,可靠性较差。

》进程间通讯(IPC)方法主要有以下几种:

管道/FIFO/共享内存/消息队列/信号

1.管道中还有命名管道和非命名管道(即匿名管道)之分,非命名管道(即匿名管道)只能用于父子进程通讯,命名管道可用于非父子进程,命名管道就是FIFO,管道是先进先出的通讯方式

2.消息队列是用于两个进程之间的通讯,首先在一个进程中创建一个消息队列,然后再往消息队列中写数据,而另一个进程则从那个消息队列中取数据。需要注意的是,消息队列是用创建文件的方式建立的,如果一个进程向某个消息队列中写入了数据之后,另一个进程并没有取出数据,即使向消息队列中写数据的进程已经结束,保存在消息队列中的数据并没有消失,也就是说下次再从这个消息队列读数据的时候,就是上次的数据!!!!

3.信号量,它与WINDOWS下的信号量是一样的,所以就不用多说了

4.共享内存,类似于WINDOWS下的DLL中的共享变量,但LINUX下的共享内存区不需要像DLL这样的东西,只要首先创建一个共享内存区,其它进程按照一定的步骤就能访问到这个共享内存区中的数据,当然可读可写

以上几种方式的比较:

1.管道:速度慢,容量有限,只有父子进程能通讯

2.FIFO:任何进程间都能通讯,但速度慢

3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题

4.信号量:不能传递复杂消息,只能用来同步

5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存

》 使用多进程的优点是:

A.父进程Crash之后,子进程还存在,可以继续干想干的事情

B.由于Android单个进程所能够使用的内存是有限制的,故多个进程可以使用更多的内存,不用担心单个进程的内存吃紧

多进程之间的通信:

A.AIDL

B.Socket
》一.Linux系统进程间通信有哪些方式?

1.socket;

2.name pipe命名管道;

3.message queue消息队列;

4.singal信号量;

5.share memory共享内存;

二.Java系统的通信方式是什么?

1.socket;

2.name pipe;

三.Android系统通信方式是什么?

Binder 通信;

四.Binder通信的优势是什么?

高效率

五.Binder通信的特点是什么?

是同步,而不是异步;

六.Binder通信是如何实现的?

1.Binder通信是通过linux的binder driver来实现的,

2.Binder通信操作类似线程迁移(threadmigration),两个进程间IPC看起来就象是一个进程进入另一个进程执行代码然后带着执行的结果返回;

3.Binder的用户空间为每一个进程维护着一个可用的线程池,线程池用于处理到来的IPC以及执行进程本地消息,Binder通信是同步而不是异步。

七. Android中的 Binder通信实现要点:

1. Android中的Binder通信是基于Service与Client的工作模型的;

2. 所有需要IBinder通信的进程都必须创建一个IBinder接口;

3. 系统中有一个进程管理所有的system service:

4. Android不允许用户添加非授权的Systemservice;

5. 现在源码开放了,我们可以修改一些代码来实现添加底层system Service的目的;

6. 对用户程序来说,我们也要创建server,或者Service用于进程间通信;

7. ActivityManagerService管理JAVA应用层所有的service创建与连接(connect),disconnect;

8. 所有的Activity也是通过这个service来启动,加载的;

9. ActivityManagerService也是加载在Systems Servcie中的;

八.Android的 Service工作流程

1.Android虚拟机启动之前系统会先启动service Manager进程;2.service Manager打开binder驱动,并通知binder kernel驱动程序这个进程将作为System Service Manager;

3.然后该进程将进入一个循环,等待处理来自其他进程的数据。4.用户创建一个System service后,通过defaultServiceManager得到一个远程ServiceManager的接口,通过这个接口我们可以调用addService函数将System service添加到Service Manager进程中;

5.然后client可以通过getService获取到需要连接的目的Service的IBinder对象,这个IBinder是Service的BBinder在binder kernel的一个参考,

6.所以serviceIBinder 在binder kernel中不会存在相同的两个IBinder对象,每一个Client进程同样需要打开Binder驱动程序。对用户程序而言,我们获得这个对象就可以通过binderkernel访问service对象中的方法。

7.Client与Service在不同的进程中,通过这种方式实现了类似线程间的迁移的通信方式,对用户程序而言当调用Service返回的IBinder接口后,访问Service中的方法就如同调用自己的函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: