进程与线程
什么是进程
进程(Process) 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。 在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念
进程的特点
- 进程是程序的一次执行过程。
- 进程是是正在运行程序的抽象。它代表运行的CPU,也称进程是对CPU的抽象。
- 系统资源(如内存、文件)以进程为单位分配。
- 操作系统为每个进程分配了独立的地址空间
- 操作系统通过“调度”把控制权交给进程。
为什么引入线程
主要归咎于两点. 一个是由实现决定的,一个是由需求决定的.
- 进程是资源调度的单位, 因此进程之间的切换的代价和开销比较大.
- 一个进程内可能需要多任务并发的执行,实现不同的功能.
什么是线程
线程(thread) 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
线程由线程ID,程序计数器(PC)[用于指向内存中的程序指令],寄存器集合[由于存放本地变量和临时变量]和堆栈[用于存放方法指令和方法参数等]组成。
进程与线程的区别
- 进程是拥有系统资源的,系统会给进程分配一个完整的虚拟地址空间.(不同进程无法共享相同的内存空间)
- 线程除了少量必要的资源外(存放本地变量),几乎不需要资源,因此它与资源分配无关。
- 进程之间相互独立,且不能共享资源
- 在同一进程的线程之间,可以共享进程的所有资源。
- 一个线程挂掉,整个进程都会跟着挂掉,而多进程应用,进程挂掉,不会影响到其他进程。多进程的程序要比多线程的程序健壮。
- 线程上下文切换的速度比进程上下文切换的快得多。
- 在多线程系统中,进程不是可执行的实体,线程才是实际的执行单位.
java线程模型
用户态和内核态
以 Unix/Linux 的体系架构为例。
因为操作系统的资源是有限的,如果访问资源的操作过多,必然会消耗过多的资源,而且如果不对这些操作加以区分,很可能造成资源访问的冲突。所以,为了减少有限资源的访问和使用冲突,对不同的操作赋予不同的执行等级(有多大能力做多大的事),用户态(User Mode)和内核态(Kernel Mode)。
运行于用户态的进程可以执行的操作和访问的资源都会受到极大的限制,而运行在内核态的进程则可以执行任何操作并且在资源的使用上没有限制。
而在用户态和内核态之间的上下文切换,不可避免的会产生一定的开销,这也是线程设计中必须考虑到的点。
线程设计的3个难点
- 在 CPU 密集型任务、I/O 密集型任务以及充分利用多核 CPU 提升程序性能上找到一个平衡点。
- 尽可能支持规模更大的线程数量。
- 减少线程在用户态(User Mode)和内核态(Kernel Mode)中切换带来的开销。
并发与并行
并发:一个时间段内有很多的线程或进程在执行,但何时间点上都只有一个在执行,多个线程或进程争抢时间片轮流执行。
并行:一个时间段和时间点上都有多个线程或进程在执行。
线程一对一模型
线程有三种模型, 一对一,多对一,多对多.具体参考 一篇文章读懂Java多线程模型, 这里只描述一对一的情况.
程序使用的是内核线程的一种高级接口——轻量级进程(Light Weight Process,LWP),轻量级进程就是我们通常意义上所讲的线程,轻量级进程也是属于用户线程。
每个用户线程都映射到一个内核线程,每个线程都成为一个独立的调度单元,由内核调度器独立调度,一个线程的阻塞不会影响到其他线程,从而保障整个进程继续工作.
优点:
- 每个线程都成为一个独立的调度单元,使用内核提供的线程调度功能及处理器映射,可以完成线程的切换,并将线程的任务映射到其他处理器上,充分利用多核处理器的优势,实现真正的并行。
缺点:
- 每创建一个用户级线程都需要创建一个内核级线程与其对应,因此需要消耗一定的内核资源,而内核资源是有限的,所以能创建的线程数量也是有限的。
- 模态切换频繁,各种线程操作,如创建、析构及同步,都需要进行系统调用,需要频繁的在用户态和内核态之间切换,开销大。
java的线程模型
Java 的线程是映射到操作系统的原生线程之上的。
JVM 没有限定 Java 线程需要使用哪种线程模型来实现, JVM 只是封装了底层操作系统的差异,而不同的操作系统可能使用不同的线程模型,例如 Linux 和 windows 可能使用了一对一模型,solaris 和 unix 某些版本可能使用多对多模型。所以一谈到 Java 语言的多线程模型,需要针对具体 JVM 实现。
Sun JDK 1.2开始,线程模型都是基于操作系统原生线程模型来实现,它的 Window 版和 Linux 版都是使用系统的 1:1 的线程模型实现的。