进程与线程的概念
进程
进程是资源分配的最小单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。然后,把该进程放入进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才真正运行。所以,进程是系统中的并发执行的单位。在Mac、Windows NT等采用微内核结构的操作系统中,它是资源分配的单位,但不是是调度运行的单位。在微内核系统中,真正调度运行的基本单位是线程。因此,实现并发功能的单位是线程。
- 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至 CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备,而进程就是用来加载指令、管理内存、管理 IO 的
- 当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程
进程就可以视为程序的一个实例。大部分程序可以同时运行多个实例进程(例如:记事本、画图、浏览器等),也有的程序只能启动一个实例进程(例如:网易云音乐、360 安全卫士等)
线程
线程是CPU调度执行的最小单位。一个进程可以包含多个线程,在大部分系统中,进程是不活动的,只是作为线程的容器。一个线程其实就是一个指令流,将指令流的一条条指令按照一定的顺序交给 CPU 执行,所以才称线程为 CPU 调度的最小单位。
一个进程之内可以分为一到多个线程
- 一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给 CPU 执行
Java 中,线程作为最小调度单位,进程作为资源分配的最小单位。 在 windows 中进程是不活动的,只是作为线程的容器
线程和进程的对比
二者的关系
一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程;进程是资源分配的最小单位,线程是操作系统可识别的最小执行和调度单位
- 资源分配给进程,同一进程的所有线程共享该进程的所有资源。 同一进程中的多个线程共享代码段(代码和常量)、数据段(全局变量和静态变量)、扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量
- CPU的时间片是分给线程而不是分给进程,即真正在处理机上运行的是线程
线程在执行过程中,需要协作同步,不同进程的线程间要利用消息通信的办法实现同步
二者的差别
进程间通信较为复杂,同一台计算机的进程通信称为 IPC,不同计算机之间的进程通信,需要通过网络,并遵守共同的协议,如:HTTP 协议;而线程通信相对简单,因为它们共享进程内的内存,比如:多个线程可以访问同一个共享变量
- 线程更轻量,线程上下文切换成本一般上要比进程上下文的切换成本低
并发与并行的概念
并发
并发其实就是多个线程在一个 CPU 核心上面进行轮流切换的串行执行。操作系统中有个组件叫做任务调度器,它的工作是把 CPU 的的时间片(windows下时间片最小约为 15 毫秒 )分给不同的指令流(即线程)。只是 CPU 在线程间进行切换的速度非常快,所以宏观上感受是多个线程在同时执行,但其实并没有真正的同时执行,还是在串行执行。像这种轮流使用同一个 CPU 核心的执行方式就叫做并发。
并行
而并行则不同与并发,并发则是多个线程在多个 CPU 核心中同时执行。因此,并发成立的前提条件一定是多个 CPU 核心。在并行中,多个线程可以同时被多个 CPU 核心执行,因此并行才是真正的多个线程同时执行。
注意:
- 单核 cpu 下,多线程不能实际提高程序运行效率,只是为了能够在不同的任务之间切换,不同线程轮流使用 cpu ,不至于一个线程总占用 cpu,别的线程没法干活
- 多核 cpu 可以并行跑多个线程,但能否提高程序运行效率还是要分情况的。有些任务,经过精心设计,将任务拆分,并行执行,当然可以提高程序的运行效率。但不是所有计算任务都能拆分(参考【阿姆达尔定律】)。也不是所有任务都需要拆分,任务的目的如果不同,谈拆分和效率没啥意义
- . IO 操作不占用 cpu,只是我们一般拷贝文件使用的是【阻塞 IO】,这时相当于线程虽然不用 cpu,但需要一直等待 IO 结束,没能充分利用线程。所以才有后面的【非阻塞 IO】和【异步 IO】优化。